ProHoster > Blog > administrasie > Circles of hell met GitHub Actions (bou van 'n CI/CD-pyplyn vir 'n Java-projek)
Circles of hell met GitHub Actions (bou van 'n CI/CD-pyplyn vir 'n Java-projek)
Ek moet dikwels 'n pyplyn bou vir bouprojekte in Java. Soms is dit oopbron, soms is dit nie. Ek het onlangs besluit om van my bewaarplekke van Travis-CI en TeamCity na GitHub Actions te probeer skuif, en dit is wat daaruit gekom het.
Wat sal ons outomatiseer?
Eerstens benodig ons 'n projek wat ons sal outomatiseer, kom ons maak 'n klein toepassing in Spring boot / Java 11 / Maven. Vir die doeleindes van hierdie artikel sal ons glad nie in die toepassingslogika belangstel nie; die infrastruktuur rondom die toepassing is vir ons belangrik, so 'n eenvoudige REST API-beheerder sal vir ons voldoende wees.
U kan die bronne hier sien: github.com/antkorwin/github-actions Alle stadiums van die bou van 'n pyplyn word weerspieël in die trekversoeke vir hierdie projek.
JIRA en beplanning
Dit is die moeite werd om te sê dat ons JIRA gewoonlik as 'n kwessiespoorder gebruik, so kom ons skep 'n aparte bord vir hierdie projek en voeg die eerste uitgawes daar by:
'n Bietjie later sal ons terugkeer na watter interessante dinge JIRA en GitHub in kombinasie kan bied.
Ons outomatiseer die samestelling van die projek
Ons toetsprojek is gebou via Maven, so bou dit is redelik eenvoudig, al wat ons nodig het is die mvn skoon pakket.
Om dit te doen met Github Actions, sal ons 'n lêer in die bewaarplek moet skep wat ons werkvloei beskryf, dit kan gedoen word met 'n gewone yml-lêer, ek kan nie sê dat ek van "yml-programmering" hou nie, maar wat kan ons doen - ons doen dit in die .github/ directory workflow/ file build.yml waarin ons die aksies sal beskryf wanneer die meestertak gebou word:
on — dit is 'n beskrywing van die geleentheid waarop ons draaiboek bekendgestel sal word.
op: pull_request/push - dui aan dat hierdie werkvloei geloods moet word elke keer as 'n stoot na die meester gemaak word en trekversoeke geskep word.
Die volgende is 'n beskrywing van die take (werksgeleenthede) en uitvoeringstappe (stappe) vir elke taak.
aanloop - hier kan ons die teiken-bedryfstelsel kies, verrassend genoeg kan u selfs Mac OS kies, maar op private bewaarplekke is dit redelik duur (in vergelyking met Linux).
gebruik laat jou toe om ander aksies te hergebruik, byvoorbeeld deur die actions/setup-java-aksie te gebruik, installeer ons die omgewing vir Java 11.
Deur middel van met ons kan die parameters spesifiseer waarmee ons die aksie begin, in wese is dit die argumente wat na die aksie oorgedra sal word.
Al wat oorbly is om die projekbou saam met Maven uit te voer: run: mvn -B clean package vlag -B sê dat ons 'n nie-interaktiewe modus nodig het sodat die maven skielik nie vir ons iets wil vra nie
Puik! Nou, elke keer as jy jou aan die meester verbind, begin die projekbou.
Outomatisering van toetsbekendstellings
Montering is goed, maar in werklikheid kan 'n projek veilig saamgestel word, maar nie werk nie. Daarom is die volgende stap om die toetslopies te outomatiseer. Daarbenewens is dit baie gerieflik om na die uitslae van die slaag van die toetse te kyk wanneer jy 'n PR-oorsig doen - jy weet verseker dat die toetse slaag en niemand het vergeet om hul tak te bestuur voordat jy 'n samesmelting doen nie.
Ons sal toetse uitvoer wanneer 'n trekversoek geskep word en saamsmelt in die meester, en terselfdertyd sal ons die skepping van 'n verslag oor kodedekking byvoeg.
Om toetse te dek, gebruik ek codecov in samewerking met die jacoco-inprop. codecov het sy eie aksie, maar dit benodig 'n teken om met ons trekversoek te werk:
${{ secrets.CODECOV_TOKEN }} - ons sal hierdie konstruksie meer as een keer sien, geheime is 'n meganisme om geheime in GitHub te stoor, ons kan wagwoorde/tokens/gashere/urls en ander data wat nie in die bewaarplekkodebasis ingesluit moet word nie, daar skryf.
U kan 'n veranderlike by geheime voeg in die bewaarplekinstellings op GitHub:
Jy kan 'n teken kry by codecov.io Na magtiging via GitHub, om 'n publieke projek by te voeg, hoef jy net 'n skakel soos hierdie te volg: GitHub-gebruikersnaam/[repo naam]. 'n Private bewaarplek kan ook bygevoeg word; om dit te doen, moet jy codecov-regte aan die toepassing in Github gee.
Nou sal die codecov-bot elkeen van ons trekversoeke invoer en 'n dekkingsveranderingsgrafiek byvoeg:
Kom ons voeg 'n statiese ontleder by
In die meeste van my oopbronprojekte gebruik ek sonarwolk vir statiese kode-analise, dit is redelik maklik om aan travis-ci te koppel. Dit is dus 'n logiese stap wanneer jy na GitHub Actions migreer om dieselfde te doen. Die aksiemark is 'n gawe ding, maar hierdie keer het dit my 'n bietjie in die steek gelaat, want uit gewoonte het ek die aksie gevind wat ek nodig gehad het en dit by die werkvloei gevoeg. Maar dit het geblyk dat sonar dit nie ondersteun deur 'n aksie vir die ontleding van projekte op maven of gradle nie. Dit staan natuurlik in die dokumentasie geskryf, maar wie lees dit?!
Dit is nie moontlik deur 'n aksie nie, so ons sal dit doen deur die mvn-inprop:
SONAR_TOKEN - kan verkry word by sonarcloud.io en jy moet dit in geheime registreer. GITHUB_TOKEN - dit is 'n ingeboude teken wat GitHub genereer, met die hulp waarvan sonarcloud[bot] by Git sal kan aanmeld om vir ons boodskappe in trekversoeke te laat.
Dsonar.projectKey - die naam van die projek in die sonar, jy kan dit in die projekinstellings sien.
Dsonar.organisasie - naam van die organisasie van GitHub.
Ons rig 'n trekversoek en wag vir sonarcloud[bot] om in die kommentaar te kom:
Vrystellingsbestuur
Die bou is opgestel, die toetse is uitgevoer, en ons kan 'n vrystelling maak. Kom ons kyk hoe GitHub Actions vrystellingbestuur baie makliker kan maak.
By die werk het ek projekte waarvan die kodebasis in bitbucket is (alles is soos in daardie storie "I write to bitbucket during the day, commit to GitHub in night"). Ongelukkig het bitbucket nie ingeboude vrystellingbestuurnutsmiddels nie. Dit is 'n probleem, want vir elke vrystelling moet jy met die hand 'n bladsy in samevloeiing skep en al die kenmerke wat by die vrystelling ingesluit is daar gooi, deur die paleise van die verstand soek, take in jira, commits in die repository. Daar is baie kanse om 'n fout te maak, jy kan iets vergeet of iets invoer wat reeds laas keer vrygestel is, soms is dit eenvoudig nie duidelik wat om 'n trekversoek te klassifiseer as - is dit 'n kenmerk of 'n foutoplossing, of redigeertoetse, of iets infrastruktuur .
Hoe kan GitHub-aksies ons help? Daar is 'n wonderlike aksie - vrystelling-opsteller, dit laat jou toe om 'n vrystellingnotas-lêer-sjabloon op te stel om kategorieë van trekversoeke op te stel en dit outomaties in die vrystellingnotas-lêer te groepeer:
Voorbeeld sjabloon vir die opstel van 'n verslag (.github/release-drafter.yml):
name-template: 'v$NEXT_PATCH_VERSION'
tag-template: 'v$NEXT_PATCH_VERSION'
categories:
- title: ' New Features'
labels:
- 'type:features'
# в эту категорию собираем все PR с меткой type:features
- title: ' Bugs Fixes'
labels:
- 'type:fix'
# аналогично для метки type:fix и т.д.
- title: ' Documentation'
labels:
- 'type:documentation'
- title: ' Configuration'
labels:
- 'type:config'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
template: |
## Changes
$CHANGES
Voeg 'n skrip by om 'n konsepvrystelling te genereer (.github/workflows/release-draft.yml):
Alle trekversoeke sal van nou af outomaties in vrystellingsnotas versamel word - magic!
Hier kan die vraag ontstaan: wat as die ontwikkelaars vergeet om etikette in die PR te plaas? Dan is dit nie duidelik in watter kategorie om dit te plaas nie, en weer sal jy dit handmatig moet hanteer, met elke PR afsonderlik. Om hierdie probleem op te los, kan ons 'n ander aksie gebruik - etiketverifikasie - dit kyk vir die teenwoordigheid van merkers op die trekversoek. As daar geen vereiste etikette is nie, sal die kontrole misluk en ons sal 'n boodskap hieroor in ons trekversoek sien.
Nou moet enige trek-versoek gemerk word met een van die etikette: tipe:fix, tipe:kenmerke, tipe:dokumentasie, tipe:toetse, tipe:konfig.
Outo-aantekening van trekversoeke
Aangesien ons so 'n onderwerp aangeraak het soos effektiewe werk met trekversoeke, is dit die moeite werd om te praat oor so 'n aksie soos etikettering, dit plaas etikette in PR gebaseer op watter lêers verander is. Byvoorbeeld, ons kan enige trekversoek wat veranderinge aan die gids bevat as [bou] merk .github/workflow.
Ek het nie daarin geslaag om die aksie wat etikette outomaties in trekversoeke plaas, te koppel met die aksie wat kontroleer vir die teenwoordigheid van vereiste etikette nie; match-label wil nie die etikette sien wat deur die bot bygevoeg is nie. Dit lyk makliker om jou eie aksie te skryf wat beide stadiums kombineer. Maar selfs in hierdie vorm is dit redelik gerieflik om te gebruik; jy moet 'n etiket uit die lys kies wanneer jy 'n trekversoek skep.
Dit is tyd om te ontplooi
Ek het verskeie ontplooiingsopsies probeer via GitHub Actions (via ssh, via scp, en met behulp van docker-hub), en ek kan sê dat jy heel waarskynlik 'n manier sal vind om die binêre na die bediener op te laai, maak nie saak hoe krom jou pyplyn is nie. is.
Ek het gehou van die opsie om die hele infrastruktuur op een plek te hou, so kom ons kyk hoe om na GitHub-pakkette te ontplooi (dit is 'n bewaarplek vir binêre inhoud, npm, jar, docker).
Skrip om 'n docker-beeld te bou en dit in GitHub-pakkette te publiseer:
Eerstens moet ons die JAR-lêer van ons toepassing bou, waarna ons die pad na die GitHub-dokker-register en die naam van ons beeld bereken. Hier is 'n paar truuks wat ons nog nie teëgekom het nie:
'n konstruksie soos: eggo "::set-uitvoer naam=NAAM::WAARDE" laat jou toe om die waarde van 'n veranderlike in die huidige stap te stel, sodat dit dan in alle ander stappe gelees kan word.
jy kan die waarde van die veranderlike wat in die vorige stap gestel is deur die identifiseerder van hierdie stap kry: ${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}
Die standaard GITHUB_REPOSITORY veranderlike stoor die naam van die bewaarplek en sy eienaar ("eienaar/repo-naam"). Om alles van hierdie reël af te sny behalwe die naam van die bewaarplek, sal ons bash-sintaksis gebruik: ${GITHUB_REPOSITORY#*/}
Om die weergawe van die prent aan te dui, gebruik ons die eerste syfers van die SHA-hash van die commit - GITHUB_SHA is daar ook nuanses hier, as jy sulke bouwerk maak nie net wanneer jy in meester saamsmelt nie, maar ook volgens die trekversoekskepping gebeurtenis, dan pas SHA moontlik nie by die hash wat ons in die git-geskiedenis sien nie, want die actions/checkout action maak sy eie unieke hash om dooiepuntaksies in die PR te vermy.
As alles goed uitgewerk het, open dan die pakkette-afdeling (https://github.com/antkorwin/github-actions/packages) in die bewaarplek, jy sal 'n nuwe docker-beeld sien:
Daar kan jy ook 'n lys weergawes van die docker-beeld sien.
Al wat oorbly, is om ons bediener op te stel om met hierdie register te werk en die diens weer te begin. Ek sal waarskynlik 'n ander keer praat oor hoe om dit deur systemd te doen.
Monitering
Kom ons kyk na 'n eenvoudige opsie oor hoe om 'n gesondheidskontrole vir ons toepassing te doen met GitHub Actions. Ons selflaaitoepassing het 'n aktuator, so ons hoef nie eers 'n API te skryf om die status daarvan na te gaan nie; ons het reeds alles vir die lui gedoen. Jy hoef net die gasheer te trek: SERVER-URL:PORT/actuator/health
Al wat ons nodig het is om 'n taak te skryf om die bediener met cron na te gaan, en as dit ons skielik nie antwoord nie, sal ons 'n kennisgewing per telegram stuur.
Laat ons eers uitvind hoe om 'n cron-werkvloei uit te voer:
Kom ons gaan die bedienerstatus handmatig na via krul:
jobs:
ping:
runs-on: ubuntu-18.04
steps:
- name: curl actuator
id: ping
run: |
echo "::set-output name=status::$(curl ${{secrets.SERVER_HOST}}/api/actuator/health)"
- name: health check
run: |
if [[ ${{ steps.ping.outputs.status }} != *"UP"* ]]; then
echo "health check is failed"
exit 1
fi
echo "It's OK"
Eerstens stoor ons in 'n veranderlike wat die bediener op die versoek gereageer het, in die volgende stap kyk ons of die status OP is en as dit nie die geval is nie, gaan ons uit met 'n fout. As jy 'n aksie met jou hande moet "oorweldig", dan uitgang 1 - geskikte wapen.
- name: send alert in telegram
if: ${{ failure() }}
uses: appleboy/telegram-action@master
with:
to: ${{ secrets.TELEGRAM_TO }}
token: ${{ secrets.TELEGRAM_TOKEN }}
message: |
Health check of the:
${{secrets.SERVER_HOST}}/api/actuator/health
failed with the result:
${{ steps.ping.outputs.status }}
Ons stuur slegs na telegram as die aksie in die vorige stap misluk het. Om 'n boodskap te stuur gebruik ons Appleboy/telegram-action; jy kan lees hoe om 'n bottoken en klets-ID in die dokumentasie te kry: github.com/appleboy/telegram-action
Moenie vergeet om in die geheime op Github te skryf nie: URL vir die bediener en tokens vir die telegram-bot.
Bonussnit - JIRA vir die lui
Ek het belowe dat ons na JIRA sal terugkeer, en ons het teruggekeer. Honderde kere het ek 'n situasie by stand-ups waargeneem wanneer ontwikkelaars 'n kenmerk gemaak het, 'n tak saamgevoeg het, maar vergeet het om die probleem na JIRA te sleep. Natuurlik, as dit alles op een plek gedoen word, sou dit makliker wees, maar in werklikheid skryf ons kode in die IDE, voeg takke saam in bitbucket of GitHub, en sleep dan die take na Jira, hiervoor moet ons nuwe vensters oopmaak , meld soms weer aan en ens. Wanneer jy perfek onthou wat jy volgende moet doen, dan is dit geen sin om die bord weer oop te maak nie. As gevolg hiervan, moet jy soggens by 'n stand-up tyd spandeer om die taakbord by te werk.
GitHub sal ons ook help met hierdie roetine-taak; Om mee te begin, kan ons probleme outomaties na die code_review-kolom sleep wanneer ons 'n trekversoek indien. Al wat jy hoef te doen is om die takbenamingskonvensie te volg:
[имя проекта]-[номер таска]-название
byvoorbeeld, as die projeksleutel "GitHub Actions" GA is, dan GA-8-jira-bot kan 'n tak wees vir die implementering van die GA-8-taak.
Integrasie met JIRA werk deur aksies van Atlassian, hulle is nie perfek nie, ek moet sê dat sommige van hulle glad nie vir my gewerk het nie. Maar ons sal slegs diegene bespreek wat beslis werk en aktief gebruik word.
Eerstens moet jy by JIRA aanmeld met die aksie: atlassian/gajira-login
Ons onttrek die taak identifiseerder uit die taknaam:
- name: Find Issue
id: find_issue
shell: bash
run: |
echo "::set-output name=ISSUE_ID::$(echo ${GITHUB_HEAD_REF} | egrep -o 'GA-[0-9]{1,4}')"
echo brach name: $GITHUB_HEAD_REF
echo extracted issue: ${GITHUB_HEAD_REF} | egrep -o 'GA-[0-9]{1,4}'
- name: Check Issue
shell: bash
run: |
if [[ "${{steps.find_issue.outputs.ISSUE_ID}}" == "" ]]; then
echo "Please name your branch according to the JIRA issue: [project_key]-[task_number]-branch_name"
exit 1
fi
echo succcessfully found JIRA issue: ${{steps.find_issue.outputs.ISSUE_ID}}
As jy in die GitHub-mark soek, kan jy 'n aksie vir hierdie taak vind, maar ek moes dieselfde ding skryf met grep met die naam van die tak, want hierdie aksie van Atlassian wou op geen manier aan my projek werk nie , om uit te vind wat daar fout was - langer as om dieselfde ding met jou hande te doen.
Al wat oorbly, is om die taak na die "Kode-hersiening"-kolom te skuif wanneer 'n trekversoek geskep word:
Daar is 'n spesiale aksie hiervoor op GitHub, al wat dit nodig het, is die kwessie-ID wat in die vorige stap verkry is en die magtiging in JIRA wat ons hierbo gedoen het.
Op dieselfde manier kan u take sleep wanneer u in die meester saamsmelt, en ander gebeurtenisse vanaf GitHub-werkvloei. Oor die algemeen hang dit alles af van jou verbeelding en begeerte om roetineprosesse te outomatiseer.
Bevindinge
As u na die klassieke DEVOPS-diagram kyk, het ons alle stadiums gedek, behalwe miskien werk, ek dink as u probeer, kan u 'n aksie in die mark vind vir integrasie met die hulptoonbankstelsel, so ons sal aanvaar dat die pyplyn gedraai het uit om deeglik te wees en gevolgtrekkings kan gemaak word op grond van die gebruik daarvan.
Pros:
Mark met klaargemaakte aksies vir alle geleenthede, dit is baie gaaf. In die meeste daarvan kan u ook na die bronkode kyk om te verstaan hoe om 'n soortgelyke probleem op te los of 'n kenmerkversoek direk aan die skrywer in die GitHub-bewaarplek te plaas.
Om die teikenplatform vir samestelling te kies: Linux, Mac OS, Windows is nogal 'n interessante kenmerk.
Github-pakkette is 'n wonderlike ding, dit is gerieflik om die hele infrastruktuur op een plek te hou, jy hoef nie deur verskillende vensters te blaai nie, alles is binne 'n radius van een of twee muisklikke en is perfek geïntegreer met GitHub Actions. Docker-registerondersteuning in die gratis weergawe is ook 'n goeie voordeel.
GitHub versteek geheime in boulogboeke, so dit is nie so skrikwekkend om dit te gebruik om wagwoorde en tekens te stoor nie. Tydens al my eksperimente kon ek nooit die geheim in sy suiwer vorm in die konsole sien nie.
Gratis vir oopbronprojekte
Nadele:
YML, wel, ek hou nie van hom nie. Wanneer jy met so 'n vloei werk, is die mees algemene commit-boodskap wat ek het "fix yml format", dan vergeet jy om 'n tab iewers te sit, of jy skryf dit op die verkeerde reël. Oor die algemeen is dit nie die lekkerste ervaring om voor 'n skerm met 'n gradeboog en liniaal te sit nie.
DEBUG, ontfouting van die vloei met commits, voer 'n herbou uit en uitvoer na die konsole is nie altyd gerieflik nie, maar dit is meer van die kategorie "jy is oordoen"; jy is gewoond daaraan om met gerieflike IDEE te werk wanneer jy enigiets kan ontfout .
Jy kan jou aksie op enigiets skryf as jy dit in Docker toedraai, maar net javascript word natuurlik ondersteun, dit is natuurlik 'n kwessie van smaak, maar ek sal iets anders verkies in plaas van js.
Volgende week tree ek saam met rapporteer by die Heisenbug 2020 Piter-konferensie. Ek sal jou nie net vertel hoe om foute te vermy wanneer jy toetsdata voorberei nie, maar ook my geheime deel om met datastelle in Java-toepassings te werk!