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.