"integrity" leistet kontinuierliche Integrationsarbeit 0

Posted by fwoeck
on Sunday, April 05

integrity führt automatisch oder manuell Test-Builds von Softwareprojekten durch – in diesem Fall von meinem aktuellen Railsprojekt. Das integrity-Frontend läuft als Thin- oder passenger-Website auf einem eigenen Server und erwartet zur Konfiguration unter anderem die git-Repoadressen der verwalteten Projekte.

Basisinstallation

# gem install foca-integrity
# gem install foca-integrity-email
# gem install ph-integrity-jabber
# gem install do_sqlite3
# gem install do_mysql

$ integrity install --passenger /var/www/integrity

Konfiguration

Die Datei /var/www/integrity/config.ru muss angepasst werden, falls Benachrichtigungen versendet werden sollen:

require "notifier/email" 
require "notifier/jabber"

und ein virtueller apache-Host muss eingerichtet werden:

<VirtualHost *:80>
  DocumentRoot /var/www/integrity/public
  ServerName integrity.int.bm.net
<Directory "/var/www/integrity/public">
allow from all
Options +Indexes
</Directory>
  ServerAlias integrity
</VirtualHost>

Die Datei config.yml enthält u.a. Datenbankeinstellungen:

:base_uri: http://integrity.int.bm.net
:database_uri: mysql://integrity:p4ssw0rd@localhost/integrity

DB-Einrichtung

Die Basisdatenbank für alle Projekte zusammen:

# mysqladmin -uroot -p create integrity
# mysql -uroot -p integrity

mysql> grant all on integrity.* to 'integrity'@'localhost' identified by 'p4ssw0rd';
mysql> flush privileges;
mysql> \q

DB-Migration

Ob es meine Ignoranz oder ein Bug war – ich musste die Migrationen für die Datenbank von integrity manuell einspielen:

CREATE TABLE `integrity_projects` (`id` INT(11) PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(50) NOT NULL, `permalink` VARCHAR(50), `uri` VARCHAR(255) NOT NULL DEFAULT '', `branch` VARCHAR(50) NOT NULL DEFAULT 'master', `command` VARCHAR(50) NOT NULL DEFAULT 'rake', `public` tinyint(1) default '1', `building` tinyint(1) default '0', `created_at` DATETIME, `updated_at` DATETIME, `build_id` INT(11), `notifier_id` INT(11))

CREATE TABLE `integrity_notifiers` (`id` INT(11) PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(50) NOT NULL, `config` TEXT NOT NULL, `enabled` tinyint(1) default '1', `project_id` INT(11))

CREATE TABLE `integrity_commits` (`id` INT(11) PRIMARY KEY AUTO_INCREMENT, `identifier` VARCHAR(50) NOT NULL default '', `message` VARCHAR(255) NOT NULL default '', `author` VARCHAR(50) NOT NULL default '', `committed_at` DATETIME NOT NULL, `created_at` DATETIME, `updated_at` DATETIME, `project_id` INT(11))

CREATE TABLE `integrity_builds` (`id` INT(11) PRIMARY KEY AUTO_INCREMENT, `started_at` DATETIME, `completed_at` DATETIME, `successful` tinyint(1) default null, `output` TEXT NOT NULL, `created_at` DATETIME, `updated_at` DATETIME, `commit_id` INT(11))

Konfiguration eines Projekts

Die folgenden Files werden im jeweiligen Projektrepo erzeugt und revisioniert, damit integrity sie bei einem Durchlauf aufrufen kann. Es erwartet einen rake-Task, der für das Build gestartet wird. Hier ist ein Beispiel:

lib/tasks/integrity.rake:

1
2
3
4
5
6
7
8
9
desc "Execute plain cucumber features in integrity"
task :integrity do
  require 'ftools'
  File.move(RAILS_ROOT+"/config/database.yml.test", RAILS_ROOT+"/config/database.yml")
  File.move(RAILS_ROOT+"/config/ldap.yml.test", RAILS_ROOT+"/config/ldap.yml")
  res = `cucumber -p plain features/plain`.split("\n")
  puts res.join("\n")
  raise if res.grep(/^\d+ failed step/).size != 0
end

An dieser Stelle kann schon einmal geprüft werden, ob der Task separat durchläuft – Achtung: er überschreibt die originalen YML-Dateien. Auf dem Entwicklungsserver:

rake integrity

Die Verarbeitung der Ausgabe nach res ist nötig, um den rake-Task scheitern zu lassen, falls ein Schritt fehlschlägt und dennoch eine sinnvolle Ausgabe im Buildlog zu sehen.

database.yml.test und ldap.yml.test

Meist werden die YML-Konfigurationsfiles nicht revisioniert. In diesem Fall musste ich zwei .test-Files erzeugen und einchecken, damit der rake-Task des Integrationsservers sie vor dem Test umkopieren kann (s.o.).

Umgebung für ruby-Enterprise

Da cucumber hier unter der apache2-Umgebung ausgeführt wird, muss diesem der rechte Pfad mitgegeben werden, d.h. in Ubuntu muss in die /etc/environment und die /etc/apache2/envvars ein /opt/ruby-enterprise/bin eingefügt werden.

Abschließende Einrichtung und Start

Nach der Vorarbeit kann nun das Frontend aufgerufen und ein erstes Testprojekt eingerichtet werden:

http://integrity.int.bm.net

Dort gibt man unter anderem Projektname und Repo an und führt den ersten Build manuell durch:

Autotests mit post-receive-Hooks

Es fehlt noch die Konfiguration von Auto-Tests via git-Postcommithooks. Am besten benutzt man das Stagingrepo dafür:

/home/git/repositories/marsxpress.git/hooks/post-receive:

wget -q --post-data="" integrity.int.bm.net/marsxpress/builds -O- >/dev/null

Damit das Script nach einem Commit aufgerufen werden kann, braucht es Ausführrechte:

chmod a+x post-receive

Benachrichtigungen mit Mail und Jabber

Hat man die enstprechenden Bibliotheken in der config.ru required (notifier/email, ...), so lässt sich die jeweilige Form im Webfrontend konfigurieren. Die Jabber-Variante habe ich beim ersten Versuch jedoch nicht zum Laufen gebracht.

Um den Mailer ohne Auth – also im Relay – zum Arbeiten zu bewegen, musste ich in der gem-Datei .../foca-integrity-email-1.0.1/lib/notifier/email.rb die Einträge für user, pass und auth entfernen. Hm.

Weblinks

  1. locomotivation.com/integrity
  2. integrityapp.com
  3. github.com/foca/integrity
Comments

Leave a response

Comment