Skrive et Jenkins-plugin

1. Oversikt

Jenkins er en åpen kildekode-kontinuerlig integreringsserver, som gjør det mulig å lage en tilpasset pluginoppretting for en bestemt oppgave / miljø.

I denne artikkelen vil vi gå gjennom hele prosessen med å lage en utvidelse som legger til statistikk i byggeproduksjonen, nemlig antall klasser og kodelinjer.

2. Oppsett

Det første du må gjøre er å sette opp prosjektet. Heldigvis gir Jenkins praktiske Maven-arketyper for det.

Bare kjør kommandoen nedenfor fra et skall:

mvn arketype: generer -Dfilter = io.jenkins.archetypes: plugin

Vi får følgende utdata:

[INFO] Genererer prosjekt i interaktiv modus [INFO] Ingen arketype definert. Bruke maven-archetype-quickstart (org.apache.maven.archetypes: maven-archetype-quickstart: 1.0) Velg archetype: 1: remote -> io.jenkins.archetypes: empty-plugin (Skjelett av et Jenkins-plugin med en POM og et tomt kildetre.) 2: fjernkontroll -> io.jenkins.archetypes: global-configuration-plugin (Skjelett til et Jenkins-plugin med en POM og et eksempel på en global konfigurasjon.) 3: remote -> io.jenkins.archetypes : hallo-world-plugin (skjelett av et Jenkins-plugin med en POM og et eksempel på byggetrinn.)

Nå velger du det første alternativet og definerer gruppe / artefakt / pakke i interaktiv modus. Etter det er det nødvendig å gjøre forbedringer i pom.xml - da den inneholder oppføringer som TODO-plugin.

3. Jenkins Plugin Design

3.1. Forlengelsespoeng

Jenkins tilbyr en rekke utvidelsespunkter. Dette er grensesnitt eller abstrakte klasser som definerer kontrakter for bestemte brukssaker og lar andre plugins implementere dem.

For eksempel består hver bygning av et antall trinn, f.eks. “Kasse fra VCS”, "Kompilere", "Test","Montere", etc. Jenkins definerer hudson.tasks.BuildStep utvidelsespunkt, slik at vi kan implementere det for å gi et tilpasset trinn som kan konfigureres.

Et annet eksempel er hudson.tasks.BuildWrapper - dette lar oss definere pre / post handlinger.

Vi har også et ikke-kjernetillegg for e-postutvidelse som definerer hudson.plugins.emailext.plugins.RecipientProvider utvidelsespunkt, som gjør det mulig å gi e-postmottakere. Et eksempel på implementering er tilgjengelig her: hudson.plugins.emailext.plugins.recipients.UpstreamComitterRecipientProvider.

Merk: det er en eldre tilnærming der plugin-klassen må utvides hudson. plugin. Derimot, Det anbefales nå å bruke utvidelsespunkter i stedet.

3.2. Plugin initialisering

Det er nødvendig å fortelle Jenkins om utvidelsen vår og hvordan den skal instantieres.

Først definerer vi en statisk indre klasse i pluginet og merker den ved hjelp av hudson. utvidelse kommentar:

klasse MyPlugin utvider BuildWrapper {@Extension offentlig statisk klasse DescriptorImpl utvider BuildWrapperDescriptor {@Override public boolean isApplicable (AbstractProject item) {return true; } @ Override public String getDisplayName () {return "name to show in UI"; }}}

For det andre må vi definere en konstruktør som skal brukes til plugins objektinstansiering og merke den av org.kohsuke.stapler.DataBoundConstructor kommentar.

Det er mulig å bruke parametere for det. De vises i brukergrensesnittet og leveres automatisk av Jenkins.

F.eks. vurdere Maven-plugin:

@DataBoundConstructor public Maven (strengemål, strengnavn, strengpom, strengegenskaper, streng jvmalternativer, boolsk brukPrivatregister, InnstillingerLeverandørinnstillinger, GlobalSettingsProvider globalSettings, boolsk injeksjonsbygningsvariabel) {...}

Det er kartlagt til følgende brukergrensesnitt:

Det er også mulig å bruke org.kohsuke.stapler.DataBoundSetter kommentar med settere.

4. Pluginimplementering

Vi har til hensikt å samle grunnleggende prosjektstatistikk under en bygging, så, hudson.tasks.BuildWrapper er den rette veien å gå her.

La oss implementere det:

klasse ProjectStatsBuildWrapper utvider BuildWrapper {@DataBoundConstructor offentlig ProjectStatsBuildWrapper () {} @Override public Environment setUp (AbstractBuild build, Launcher launcher, BuildListener lytter) {} @Extension public static class DescriptorImpl utvider BuildWrapperDescriptorable {@OoolProjectReactor = ekte; } @Nonnull @Override public String getDisplayName () {return "Konstruer prosjektstatistikk under bygging"; }}}

Ok, nå må vi implementere den faktiske funksjonaliteten.

La oss definere en domeneklasse for prosjektstatistikken:

klasse ProjectStats {private int klasserNummer; private int linjerNummer; // standardkonstruktører / getters}

Og skriv koden som bygger dataene:

private ProjectStats buildStats (FilePath root) kaster IOException, InterruptedException {int classesNumber = 0; int linesNumber = 0; Stack toProcess = new Stack (); toProcess.push (root); mens (! toProcess.isEmpty ()) {FilePath path = toProcess.pop (); hvis (path.isDirectory ()) {toProcess.addAll (path.list ()); } annet hvis (path.getName (). endsWith (". java")) {classesNumber ++; linesNumber + = countLines (sti); }} returner nye ProjectStats (classesNumber, linesNumber); }

Til slutt må vi vise statistikken til sluttbrukere. La oss lage en HTML-mal for det:

    $ PROJECT_NAME $ Prosjekt $ PROJECT_NAME $: 
KlassenummerLinjenummer
$ CLASSES_NUMBER $$ LINES_NUMBER $

Og fyll den under byggingen:

offentlig klasse ProjectStatsBuildWrapper utvider BuildWrapper {@Override public Environment setUp (AbstractBuild build, Launcher launcher, BuildListener listener) {return new Environment () {@Override public boolean tearDown (AbstractBuild build, BuildListener listener) kaster IOException, InterruptedExceptionStat = ProjectStats (ProjectStats) build.getWorkspace ()); Strengrapport = createReport (build.getProject (). GetDisplayName (), statistikk); Fil artefakterDir = build.getArtifactsDir (); Strengsti = artefakterDir.getCanonicalPath () + REPORT_TEMPLATE_PATH; File reportFile = new File ("path"); // skriv rapportens tekst til rapportens fil}}; }}

5. Bruk

Det er på tide å kombinere alt vi har laget så langt - og se det i aksjon.

Det antas at Jenkins er i gang i lokalmiljøet. Se installasjonsdetaljene ellers.

5.1. Legg til pluginet til Jenkins

La oss nå bygge pluginet vårt:

mvn installere

Dette vil skape en * .hpi filen i mål katalog. Vi må kopiere den til Jenkins-programtilleggskatalogen (~ / .jenkins / plugin som standard):

cp ./target/jenkins-hello-world.hpi ~ / .jenkins / plugins /

Til slutt, la oss starte serveren på nytt og sørge for at programtillegget brukes:

  1. Åpne CI-dashbordet kl // lokal vert: 8080
  2. Navigere til Administrer Jenkins | Administrer programtillegg | Installert
  3. Finn pluginet vårt

5.2. Konfigurer Jenkins Job

La oss lage en ny jobb for et åpen kildekode Apache commons-lang-prosjekt og konfigurere banen til Git repo der:

Vi må også aktivere pluginet vårt for det:

5.3. Sjekk resultatene

Vi er klare nå, la oss sjekke hvordan det fungerer.

Vi kan bygge prosjektet og navigere til resultatene. Vi kan se at a stats.html filen er tilgjengelig her:

La oss åpne den:

Det var det vi forventet - en enkelt klasse som har tre kodelinjer.

6. Konklusjon

I denne opplæringen opprettet vi en Jenkins plugin fra bunnen av og sørget for at den fungerer.

Naturligvis dekket vi ikke alle aspekter av utviklingen av CI-utvidelser, vi ga bare en grunnleggende oversikt, designideer og et første oppsett.

Og som alltid kan kildekoden bli funnet på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found