
Mul on sageli vaja ehitada pipeline'i Java projektide kokku panemiseks. Mõnikord on need avatud lähtekoodiga, mõnikord mitte. Hiljuti otsustasin proovida osa oma repotest Travis-CI ja TeamCity üle viia GitHub Actions'i ning siin on, mis sellest välja tuli.
Mida me automatiseerime
Alustuseks vajame projekti, mida automatiseerime, teeme väikese rakenduse Spring boot / Java 11 / Maven. Käesolevas artiklis ei huvita meid rakenduse loogika, vaid infrastruktuur rakenduse ümber, seega piisab meile lihtsast REST API kontrollerist.
Koodi saab vaadata siit: kõik pipeline'i ehitamise etapid on kajastatud selle projekti pull-request'ides.
JIRA ja planeerimine
Tuleb mainida, et me kasutame tavaliselt JIRA't ülesannete jälgimiseks, seega loome selle projekti jaoks eraldi laua ja lisame sinna esimesed ülesanded:

Hiljem naaseme veel selle juurde, mida huvitavat võivad JIRA ja GitHub koos pakkuda.
Automatiseerime projekti kokku panemise
Meie testprojekt on kokku pandud maveniga, nii et selle ehitamine on üsna lihtne, kõik, mis meil vaja, on mvn clean package.
Selle tegemiseks GitHub Actions'i abil peame looma repozitooriumis faili meie töövoo kirjeldusega, seda saab teha tavalise yml-failina, ma ei saa öelda, et mulle meeldib «yml'i programmeerimine», aga mis seal teha — loome kausta .github/workflow/ faili build.yml, milles kirjeldame tegevusi master haru ehitamisel:
name: Build
on:
pull_request:
branches:
- '*'
push:
branches:
- 'master'
jobs:
build:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 1.11
- name: Maven Package
run: mvn -B clean package -DskipTests
on — see on sündmuse kirjeldus, mille järgi meie skript käivitub.
on: pull_request / push — ütleb, et seda töövoogu tuleb käivitada iga kord, kui pusime masterisse ja loome pull-request'e.
Edasi tuleb ülesannete kirjeldus (töödeks) ja täitmisetapid (steps) iga ülesande jaoks.
runs-on — siin saame valida siht-operatsioonisüsteemi, üllataval kombel saab valida isegi Mac OS-i, kuid privaatsete repode puhul on see üsna kulukas luksus (võrreldes linuxiga).
uses võimaldab taaskasutada teisi toiminguid, näiteks kasutame toimingu actions/setup-java abil Java 11 keskkonna seadistamiseks.
Käesoleva kaudu with saame saame määrata parameetrid, millega me tegevust käivitame, need on põhimõtteliselt argumendid, mis antakse edasi aktsioonile.
Jääb üle vaid käivitada Maveniga projekti koostamine: run: mvn -B clean package Teised -B ütleb, et meil on vaja non-interactive mode'i, et Maven ei küsiks meilt äkki midagi.

Suurepärane! Nüüd, iga commitiga masterisse, käivitatakse projekti koostamine.
Automatiseerime testide käivitamise
Koostamine on hea, kuid tegelikkuses võib projekt kenasti kokku tulla, aga mitte töötada. Seetõttu tuleb järgmise sammuna tegeleda testide automaatse käitamisega. Samuti on väga mugav vaadata testide tulemusi, kui teed PR-i ülevaatust — sa tead täpselt, et testid läbivad ja keegi ei ole unustanud enne merge'i oma haru läbivaatamist.
Käivitame testid pull requesti loomisel ja masterisse merge'imisel ning lisame ka code-coverage'i aruande koostamise.
name: Build
on:
pull_request:
branches:
- '*'
push:
branches:
- 'master'
jobs:
build:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: seadista JDK 11
uses: actions/setup-java@v1
with:
java-version: 1.11
- name: Maven Verify
run: mvn -B clean verify
- name: Test Coverage
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
Testide katmiseks kasutan codecov'i koos jacoco plugina. Codecovi jaoks on olemas oma aktsioon, kuid selleks, et see meie pull request'iga töötaks, on tal vaja tokenit:
${{ secrets.CODECOV_TOKEN }} — sellist konstruktsiooni kohtame veel mitu korda, secrets on mehhanism saladuste hoidmiseks GitHubis, saame sinna kirjutada paroole/tokenid/hoste/url-e ja muid andmeid, mida ei peaks koodibaasis näitama.
Muuda muutuja secrets'ides, saab GitHubi repositooriumi seadetes:

Tokeni saab kätte pärast GitHub'iga sisselogimist, avaliku projekti lisamiseks piisab lihtsalt järgima lingi tüüpi: /[repo name]. Приватный репозиторий тоже можно добавить, для этого надо дать права codecov приложению в гитхабе.

Lisame jacoco plugina POM-faili:
org.jacoco
jacoco-maven-plugin
0.8.4
prepare-agent
report
phase>test
report
org.apache.maven.plugins
maven-surefire-plugin
2.22.2
plain
**/*Test*.java
**/*IT*.java
Nüüd lisab iga meie pull-requesti codecov bot ja lisab katvuse muudatuste graafiku:

Lisame staatilise analüsaatori
Enamikus oma avatud lähtekoodiga projektides kasutan staatilise koodi analüüsimiseks sonar cloud'i, mis on üsna lihtne ühendada travis-ci'ga. Seega on loogiline samm migreerimisel GitHub Actions'i, teha sama. Actionide turg on äge asi, kuid seekord vedas see natuke alt, sest leidsin harjumusest vajaliku action'i ja määrasin selle töövoos. Kuid selgus, et sonar ei toeta maven või gradle projektide analüüsimiseks action'i kaudu töötamist. Sellest on loomulikult dokumentatsioonis kirjutatud, aga kes seda loeb?!
Action'iga ei saa, seega teeme läbi mvn plugina:
name: SonarCloud
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened]
jobs:
sonarcloud:
runs-on: ubuntu-16.04
steps:
- uses: actions/checkout@v1
- name: Set up JDK
uses: actions/setup-java@v1
with:
java-version: 1.11
- name: Analyze with SonarCloud
# set environment variables:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
# run sonar maven plugin:
run: mvn -B verify sonar:sonar -Dsonar.projectKey=antkorwin_github-actions -Dsonar.organization=antkorwin-github -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.coverage.jacoco.xmlReportPaths=./target/site/jacoco/jacoco.xml
SONAR_TOKEN — saab saada ja tuleb see määrata secrets'is. GITHUB_TOKEN — see on sisseehitatud token, mille genereerib GitHub, selle abil saab sonarcloud[bot] Git'is autentida, et jätta meile kommentaare pull-request'ides.
Dsonar.projectKey — projekti nimi sonaris, mille saab vaadata projekti seadetes.
Dsonar.organization — organisatsiooni nimi GitHubis.
Teeme pull-request'i ja ootame, kuni sonarcloud[bot] kommentaaridesse tuleb:

Väljalaske haldus
Build on seadistatud, testid on läbitud, saame ka väljalasu teha. Vaadakem, kuidas GitHub Actions aitab oluliselt lihtsustada väljalaske haldust.
Tööl on mul projekte, mille koodibaas asub bitbucketis (kõik nagu selles loos „päeval kirjutan bitbucketisse, öösel kommitan GitHubi“). Kahjuks ei ole bitbucketis sisseehitatud vahendeid väljaannete haldamiseks. See on probleem, kuna iga väljaande jaoks tuleb käsitsi luua leht confluence'is, kuhu on kogutud kõik funktsioonid, mis on väljaandes, läbi kaevata mõttemõlgutused, ülesanded jira's, commit'id hoidlas. Palju on eksimisvõimalusi, midagi võib ununeda või kirjutada seda, mis juba varem välja anti, mõnikord on lihtsalt raske aru saada, millise pull-requestiga on tegu — kas see on funktsioon, bugi parandus, testide parandamine või midagi infrastruktuuri seadistamise kohta.
Kuidas võib GitHubi toimingud aidata? On olemas suurepärane toiming — release drafter, see võimaldab seada väljaannetega seotud märkmete faili mallid, et määrata pull-requestide kategooriaid ja automaatselt neid rühmitada väljaande märkmete failis:

Näide raporti seadistamise mallist (.github/release-drafter.yml):
name-template: 'v$NEXT_PATCH_VERSION'
tag-template: 'v$NEXT_PATCH_VERSION'
categories:
- title: ' Uued funktsioonid'
labels:
- 'type:features'
# Sellesse kategooriasse kogume kõik PR-d, millel on märge type:features
- title: ' Bugi parandused'
labels:
- 'type:fix'
# Samamoodi märkega type:fix jne.
- title: ' Dokumentatsioon'
labels:
- 'type:documentation'
- title: ' Seadistus'
labels:
- 'type:config'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
template: |
## Muudatused
$CHANGES
Lisame skripti väljaande mustandi genereerimiseks (.github/workflows/release-draft.yml):
name: "Loo mustand väljaanne"
on:
push:
branches:
- master
jobs:
update_draft_release:
runs-on: ubuntu-18.04
steps:
- uses: release-drafter/release-drafter@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Alates sellest hetkest hakkavad kõik pull-requestid automaatselt koguma väljaande märkmeid — maagia!
Siin võib tekkida küsimus: ent mis siis, kui arendajad unustavad PR-ides märgid määrata? Siis ei ole selge, millisesse kategooriasse see tuleks kuulutada ja jälle tuleb iga PR-i eraldi käsitsi lahendada. Selle probleemi lahendamiseks võime kasutada veel üht toimingut — label verifier — see kontrollib, kas pull-requestil on sildid. Kui ühtegi kohustuslikku silti ei ole, siis on kontroll ebaõnnestunud ja näeme sellest teavet meie pull-requestis.
name: "Kontrolli tüübi siltide olemasolu"
on:
pull_request:
types: [opened, labeled, unlabeled, synchronize]
jobs:
triage:
runs-on: ubuntu-18.04
steps:
- uses: zwaldowski/match-label-action@v2
with:
allowed: 'type:fix, type:features, type:documentation, type:tests, type:config'
Nüüd peab igal pull-requestil olema üks siltidest: type:fix, type:features, type:documentation, type:tests, type:config.

Automaatne pull-requestide annotatsioon
Kuna me oleme arutanud tõhusat tööd pull-requestidega, siis tasub rääkida ka sellisest tegevusest nagu labeler, mis lisab PR-idele silte selle põhjal, millised failid on muudetud. Näiteks võime märgistada kui [build] mis tahes pull-request, kus on muudatusi kaustas .github/workflow.
Selle seadistamine on üsna lihtne:
name: "Automaatne teemade määramine PR-idele"
on:
- pull_request
jobs:
triage:
runs-on: ubuntu-18.04
steps:
- uses: actions/labeler@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
Me vajame ka faili, mis kirjeldab vastavust projekti kaustade ja pull-requestide teemade vahel:
theme:build:
- ".github/**"
- "pom.xml"
- ".travis.yml"
- ".gitignore"
- "Dockerfile"
theme:code:
- "src/main/*"
theme:tests:
- "src/test/*"
theme:documentation:
- "docs/**"
theme:TRASH:
- ".idea/**"
- "target/**"
Mul ei õnnestunud automaatse silte määramise tegevust ja tegevust, mis kontrollib kohustuslike silte, omavahel siduda; match-label ei taha kuidagi näha botiga määratud silte. Tundub, et lihtsam on kirjutada oma tegevus, mis kombineerib mõlemad etapid. Kuid isegi sellisel kujul on kasutamine üsna mugav, tuleb valida silt loomiseks pull-requesti.
On aeg juurutamiseks

Proovisin mitmeid võimalusi juurutamiseks GitHub Actions'i kaudu (ssh, scp ja docker-hubi abil), ja võin öelda, et tõenäoliselt leiate viisi, kuidas binaarfaile serverisse laadida, ükskõik kui keeruline ka teie voog ei oleks.
Mulle meeldis võimalus hoida kogu infrastruktuur ühes kohas, seega vaatame, kuidas teha juurutamist GitHub Packages'isse (see on repositoorium binaarsisule, npm, jar, docker).
Docker pildi ehitamise ja selle GitHub Packages'i avaldamise skript:
nimi: Rakenda docker pilt
kuna:
push:
harud:
- 'master'
töökohad:
build_docker_image:
töötab: ubuntu-18.04
sammud:
# Koosta JAR:
- kasutab: actions/checkout@v1
- nimi: seadista JDK 11
kasutab: actions/setup-java@v1
koos:
java-versioon: 1.11
- nimi: Maven pakett
käivita: mvn -B clean compile package -DskipTests
# Seadista globaalsed keskkonnamuutujad:
- nimi: seadista globaalne keskkond
id: global_env
käivita: |
echo "::set-output name=IMAGE_NAME::${GITHUB_REPOSITORY#*\/}"
echo "::set-output name=DOCKERHUB_IMAGE_NAME::docker.pkg.github.com\/${GITHUB_REPOSITORY}\/${GITHUB_REPOSITORY#*\/}"
# Koosta Docker pilt:
- nimi: Koosta ja märgista pilt
käivita: |
docker build -t "${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}:latest" -t "${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}:${GITHUB_SHA::8}" .
- nimi: Docker sisselogimine
käivita: docker login docker.pkg.github.com -u $GITHUB_ACTOR -p ${{secrets.GITHUB_TOKEN}}
# Avalda pilt GitHub paketirepositooriumisse:
- nimi: Avalda pilt
keskkond:
IMAGE_NAME: $GITHUB_REPOSITORY
käivita: docker push "docker.pkg.github.com\/$GITHUB_REPOSITORY\/${{ steps.global_env.outputs.IMAGE_NAME }}"
Esiteks peame koostama oma rakenduse JAR-faili, seejärel arvutame GitHub docker registri tee ja meie pildi nime. Siin on mõned nipid, millega me veel kokku ei ole puutunud:
- konstantse väljend, nagu: echo «::set-output name=NAME::VALUE», võimaldab määrata muutujate väärtusi praeguses etapis, et neid saaks seejärel lugeda kõigis teistes etappides.
- Muutujate väärtust, mis on määratud eelnevas etapis, saab positiivselt lugeda selle etapi identifikaatori kaudu: ${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}
- Standardai muutujas GITHUB_REPOSITORY hoitakse hoidla nime ja selle omanikku («owner\/repo-name»). Selleks, et eemaldada sellest stringist kõik peale hoidla nime, kasutame bash süntaksit: ${GITHUB_REPOSITORY#*\/}
Seejärel peame koostama docker-pildi:
docker build -t "docker.pkg.github.com\/antkorwin\/github-actions\/github-actions:latest"
Logige sisse registrisse:
docker login docker.pkg.github.com -u $GITHUB_ACTOR -p ${{secrets.GITHUB_TOKEN}}
Ja avaldage pilt GitHub Packages Repository's:
docker push "docker.pkg.github.com\/antkorwin\/github-actions\/github-actions"
Pildi versiooni määramiseks kasutame komiti SHA-hash'i esimesi numbreid — GITHUB_SHA on siin samuti nüansside rikka, kui teete selliseid koostamisi mitte ainult mergimise ajal masterisse, vaid ka pull-requesti loomise sündmuse põhjal, kuna actions\/checkout tekitab oma ainulaadse hash'i, et vältida tegevuste vastastikust lukustumist PR-is.

Kui kõik läks sujuvalt, siis avades pakettide jaotise (https:\/\/github.com\/antkorwin\/github-actions\/packages) hoidlas, näete uut docker-pilti:

Sealt saab vaadata dokkerpildi versioonide nimekirja.
Küsimus on ainult meie serveri seadistamises selle registri jaoks ja teenuse taaskäivitamine. Kuidas seda teha läbi systemd, sellest räägin ma võib-olla teinekord.
Jälgimine
Vaadakem lihtsat varianti, kuidas teha meie rakenduse tervisekontrolli GitHub Actionsi abil. Meie algrakenduses on actuator, nii et API selle oleku kontrollimiseks pole isegi vaja kirjutada, kõik on juba sinu eest tehtud. Peab lihtsalt hosti kutsuma: SERVER-URL:PORT/actuator/health
$ curl -v 127.0.0.1:8080/actuator/health
> GET /actuator/health HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.61.1
> Accept: */*
< HTTP/1.1 200
< Content-Type: application/vnd.spring-boot.actuator.v3+json
< Transfer-Encoding: chunked
< Date: Thu, 04 Jun 2020 12:33:37 GMT
{"status":"UP"}
Kõik, mida meil on vaja — kirjutada ülesanne serveri kontrollimiseks croni kaudu, ja kui ta meile ei vasta, saadame teate telegrammi.
Esiteks vaatame, kuidas käivitada workflow croni kaudu:
on:
schedule:
- cron: '*/5 * * * *'
Kõik on lihtne, isegi ei usu et GitHubis saab teha selliseid üritusi, mis ei mahu üldse webhook'e. Detailid on dokumentatsioonis:
Kontrollime serveri staatust käsitsi curl'i abil:
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"
Esiteks salvestame muutuja, mille server vastas päringule, järgmises etapis kontrollime, et staatus on UP ja kui see pole nii, väljume veaga. Kui on vaja käsitsi 'tappa' tegevus, siis exit 1 — sobiv relv.
- 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 }}
Telegrammi saatmine toimub ainult siis, kui tegevus ebaõnnestus eelmisel sammul. Teate saatmiseks kasutame appleboy/telegram-action, kuidas saada bot'i token ja vestluse id, saab lugeda dokumentatsioonist:

Ärge unustage lisada GitHubi saladustesse: serveri URL ja bot'i tokenid telegrammi jaoks.
Boonusraja — JIRA laiskadele
Lubasin, et me naasime JIRA juurde ja me tõesti naasesime. Olen sadades seistes tähele pannud, et arendajad on loonud funktsiooni, sulgenud haru, kuid unustanud ülesande JIRA-sse tõsta. Loomulikult oleks kõik lihtsam, kui kõik toimub ühes kohas, kuid tegelikult kirjutame me koodi IDE-s, sulgeme harud bitbucketis või GitHubis ja tõstame ülesandeid siis JIRA-sse, mis nõuab uute akende avamist, mõnikord peab uuesti sisse logima jne. Kui sa oled täiesti kindel, mida edasi teha, ei ole mõtet avada tahvlit veel kord. Lõpuks peab hommikul seistes kulutama aega ülesannete tahvli ajakohastamiseks.
GitHub aitab meid ka sel rutiinsel tegevusel, alguses saame automaatselt tõsta ülesandeid koodivaatamise kolonni, kui oleme teinud pull-requesti. Kõik, mis on vajalik - järgida harude nimetamise kokkulepet:
[projekti_nimi]-[ülesande_numbr]-nimetus
näiteks, kui projekti võti 'GitHub Actions' on GA, siis GA-8-jira-bot võib olla haru, mis rakendab ülesannet GA-8.
Integratsioon JIRA-ga toimib Atlassiani toimingute kaudu, need ei ole ideaalsed, pean ütlema, et mõned neist ei toiminud mul üldse. Kuid arutame ainult neid, mis tõeliselt töötavad ja mida aktiivselt kasutatakse.
Kuna on vaja kõigepealt JIRA-s sisse logida järgmise toimingu abil: atlassian/gajira-login
jobs:
build:
runs-on: ubuntu-latest
name: Jira Workflow
steps:
- name: Logi sisse
uses: atlassian/gajira-login@master
env:
JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
Selleks tuleb JIRA-s saada token, kuidas seda teha on siin kirjas:
Tõstame ülesande identifikaatori haru nimest:
- name: Leia Ülesanne
id: find_issue
shell: bash
run: |
echo "::set-output name=ISSUE_ID::$(echo ${GITHUB_HEAD_REF} | egrep -o 'GA-[0-9]{1,4}')"
echo haru nimi: $GITHUB_HEAD_REF
echo välja tõmmatud ülesanne: ${GITHUB_HEAD_REF} | egrep -o 'GA-[0-9]{1,4}'
- name: Kontrolli Ülesannet
shell: bash
run: |
if [[ "${{steps.find_issue.outputs.ISSUE_ID}}" == "" ]]; then
echo "Palun nimetage oma haru vastavalt JIRA ülesandele: [projekti_võti]-[ülesande_number]-haru_nimi"
exit 1
fi
echo edukalt leitud JIRA ülesanne: ${{steps.find_issue.outputs.ISSUE_ID}}
Kui otsida GitHubi turult, siis võib leida selle ülesande jaoks toimingu, kuid ma pidin kirjutama sama kasutades grep haru nime järgi, kuna see Atlassiani toiming ei töötanud minu projektis, uurida, mis seal vale on - on aeglasem kui kätega sama asja tegemine.
Jääb vaid ülesanne „Code review“ veergu tõsta, kui luua pull-request:
- name: Ülesande üleminek
if: ${{ success() }}
uses: atlassian/gajira-transition@master
with:
issue: ${{ steps.find_issue.outputs.ISSUE_ID }}
transition: "Code review"
Selleks on GitHubis spetsiaalne tegevus, ainus, mida see vajab, on eelmisel sammul saadud ülesande ID ja autentimine JIRA-s, mille me tegime eespool.

Nii saab ülesandeid tõmmata ka merge'ides masterisse ja muudes GitHubi töövoogudes. Üldiselt oleneb kõik teie kujutlusvõimest ja soovist rutiinseid protsesse automatiseerida.
Järeldused
Kui vaadata klassikalist DEVOPS diagrammi, siis oleme katnud kõik etapid, välja arvatud operate, arvan, et kui pingutada, võib leida mõne tegevuse turult, et integreerida abi süsteemiga, seega võime arvata, et pipeline on korralik ja selle kasutamise põhjal saab järeldusi teha.

Plussid:
- Turul on valmistooted, mis katavad igasuguseid olukordi, see on väga lahe. Enamikul neist on ka allikaid võimalik vaadata, et mõista, kuidas sarnast ülesannet lahendada või postitada feature request autorile otse GitHubi repole.
- Eesmärgiks valitud platvormi valimine: Linux, mac os, windows on üsna huvitav funktsioon.
- Github Packages on suurepärane asi, hoida kogu infrastruktuur ühes kohas on mugav, pole vaja sirvida erinevatesse akendesse, kõik on ühe või kahe hiirekliki kaugusel ja kenasti integreeritud GitHub Actionsiga. Docker registry toetus tasuta versioonis on ka hea eelis.
- GitHub peidab saladusi ehituse logides, seega pole hirmutav neid paroolide ja tokenite hoidmiseks kasutada. Kõigi katsete jooksul ei ole mul õnnestunud kordagi näha saladust puhtal kujul konsoolis.
- Tasuta avatud lähtekoodiga projektide jaoks
Miinused:
- YML, ma ei armasta seda. Selles voos töötades on minu kõige sagedasem commit message „fix yml format“, siis unustan kuskil tab'i panna, siis kirjutad valele reale. Üldiselt pole ekraani ees transportööriga istumine ja joonlauaga mõõtmine kõige meeldivam tegevus.
- DEBUG, voogu on ebamugav jagada commitidega, uuesti ehitades ja konsooli väljundis, kuid see on rohkem kategooria „te olete ära hellitatud“, harjunud töötama mugavate IDEA-dega, kus saab kõike debaadida.
- Oma aktsiooni saab kirjutada millega iganes, kui see on Dockerisse pakitud, kuid ainus natiivne tugi on JavaScriptile. Loomulikult on see maitse küsimus, kuid mina eelistaksin midagi muud kui js.
Tuletan meelde, et kõigi skriptide repo on siin:
Nädala pärast esinen konverentsil Heisenbug 2020 Piter. Räägin mitte ainult sellest, kuidas vältida vigu testandmete ettevalmistamisel, vaid jagan ka oma saladusi andmekogumitega töötamisel Java rakendustes!
Allikas: habr.com
