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
- locomotivation.com/integrity
- integrityapp.com
- github.com/foca/integrity