á¤ááąáŦááēá¸ááĢá¸áááē GitLab ááᯠáĄáá¯áļá¸ááŧá¯á sonatype áážááˇáē/ááá¯áˇááá¯ááē maven áááá¯ááá¯áážáąáŦááēáááēá¸ááģáŦá¸ááŊááē áááēá¸ááá¯áˇá áá¯ááēáá¯ááēááģáŦá¸ááᯠááģááēááŧááēá áŊáŦ áá¯ááēááąááá¯áááˇáē java developer ááģáŦá¸áĄááŊááē áááēááŊááēááĢáááēá á¤ááąáŦááēá¸ááĢá¸ááŊááē á¤ááŧáŋááŦááá¯ááŧáąáážááēá¸áááē gitlab-runnerá gitlab-ci áážááˇáē maven-plugin ááá¯áááēááąáŦááēááŧááēá¸áĄááŧáąáŦááēá¸ááŧáąáŦááĢáááēá
ááá¯áĄááēááģááēááģáŦá¸
- mvn áážááˇáē GPG ááąáŦáˇááģáŦá¸ááᯠáá¯áļááŧá¯áļá áŊáŦááááēá¸áááēá¸ááĢá
- áĄááģáŦá¸áá°áážáŦ CI áá¯ááēáááēá¸ááģáŦá¸ááᯠáá¯áļááŧá¯áļá áŊáŦ áĄááąáŦááēáĄáááēááąáŦáēááŧááēá¸á
- áážáąá¸ááąáŦááēá¸áá ášá ááēá¸ááģáŦḠ(áá¯ááēááŊážááēááŧááēá¸/ááģážááēáá áēááŧááē) ááᯠáĄááģáŦá¸áá°áážáŦ ááá¯áážáąáŦááēááŦááģáŦá¸ááá¯áˇ áĄááēáá¯ááēáá¯ááēááŧááēá¸á
- maven Central ááŊááē áá¯ááēááąáááēáĄááŊááē ááŊááēáážáááąáŦááŦá¸áážááēá¸ááģáŦá¸ááᯠáĄááá¯áĄááģáąáŦááēá á áēááąá¸ááŧááēá¸á
- áááąáŦááģááēááģáŦá¸á áŊáŦáĄááŊááē áážáąá¸ááąáŦááēá¸áá ášá ááēá¸ááģáŦá¸ááᯠááá¯áážáąáŦááēáá¯áļááá¯áˇ áĄááēáá¯ááēáááēááŧááēá¸áĄááŊááē ááąáá¯ááģááŧáąáážááēá¸ááģááēá
- ááá¯á¸áážááēá¸áážá¯áážááˇáē áĄáá¯áļá¸ááŧá¯áááŊááēáá°ááŧááēá¸á
áĄááŧáąáŦááēá¸áĄááŦ
ááąáá¯ááģááááēá¸áĄááģááēáĄáááē
- Sonatype OSS Repository Hosting Service áážáá áēáááˇáē Maven Central ááŊááē áážáąá¸ááąáŦááēá¸áá ášá ááēá¸ááģáŦḠááŧááˇáēááģááááˇáē ááášáááŦá¸á áĄááąá¸á áááēááąáŦáēááŧááģááēááᯠááŊááē ááąáŦáēááŧááŦá¸ááŧáŽá¸ááŧá áēáááēá áĄáá¯áļá¸ááŧá¯áá°ááᯠááá¯áˇááŧáąáŦááˇáē ááģáŊááēá¯ááēáááē á¤ááąáŦááēá¸ááĢá¸ááᯠáážááēáááēááąáŦááąááŦááģáŦá¸ááŊááē ááá¯á¸ááŦá¸ááĢáááēá
- ááŧáá¯áááēá áŦáááēá¸ááąá¸ááŊááēá¸ááĢá ááá¯áážáąáŦááēáá¯áļááá¯ááŊááˇáēáááē áááēáážááēáá áēá áąáŦááēááá¯ááŊááˇáēááĢ (áĄááąá¸á áááēáĄááģááēáĄáááēááģáŦá¸áĄááŊááē áĄááá¯ááēá¸ááᯠáááēáážá¯ááĢá ) repository ááá¯ááŊááˇáēááŧáŽá¸ááąáŦááēá JIRA ááž ááąáŦáˇááēáĄááē/á ááŦá¸áážááēáĄááŊᲠ(ááá¯ááąáŦááēááá¯ááēá¸ááŊááē Sonatype áĄááąáŦááˇáēáĄááŧá áēáááēááŊážááēá¸áááē) ááᯠSonatype nexus ááá¯áˇ áážáąá¸ááąáŦááēá¸áá ášá ááēá¸ááģáŦḠáĄááēáá¯ááēáá¯ááēáááēáĄááŊááē áĄáá¯áļá¸ááŧá¯ááĢáááēá
- ááá¯áˇááąáŦááēá GPG ááąáŦáˇáá¯ááēááąá¸ááŧááēá¸áá¯ááēáááēá¸á ááēááᯠáĄááŊááēááŧáąáŦááēááŊáąáˇá áŊáŦááąáŦáēááŧáááēá áĄááąá¸á áááēáĄááģááēáĄáááēááģáŦá¸áĄááŊááē ááášáááᯠááŧááˇáēááĢá
- áááēáĄáá¯áļá¸ááŧá¯ááąáááēááá¯áááē Linux GPG key (gnupg/gnupg2) áá¯ááēáá¯ááēááá¯áˇáĄááŊááē console ááᯠinstall áá¯ááēáááĢáááēá entropy ááá¯áá¯ááēáá¯ááēáááēá ááá¯ááēááĢá ááąáŦáˇááģáá¯á¸áááēáááē áĄááŊááēáĄááģáááēáá°áááąáááēá
- ááá¯áážáąáŦááēááŧááēá¸áááēááąáŦááēáážá¯ááģáŦḠáĄááģáŦá¸áá°áážáŦ GPG ááąáŦáˇááģáŦá¸
GitLab ááŊááē ááŧááˇáēááģááē áááąáŦááģááēáá áēáᯠáááēááąáŦááēááŧááēá¸á
- ááááĻá¸á áŊáŦá áááēáááē áážáąá¸ááąáŦááēá¸áá ášá ááēá¸ááģáŦá¸ááᯠáĄáá¯áļá¸ááģáááēáĄááŊááē ááá¯ááēááá¯ááēá¸ááᯠááááēá¸áááēá¸áááˇáē áááąáŦááģááēáá áēáá¯ááᯠáááēááŽá¸ááŧáŽá¸ ááŧááēáááēáááēáážááēáááē ááá¯áĄááēáááēá ááģáŊááēá¯ááēá áááąáŦááģááēááᯠááá¯á¸ááá¯á¸áážááēá¸áážááēá¸áážááˇáē áážá¯ááēááŊáąá¸á áŊáŦ áĄáááēááąá¸áá˛áˇááĢáááēá
- repository ááá¯áááēááŽá¸ááŧáŽá¸ááąáŦááēá repository ááá¯ááŧáąáŦááēá¸áá˛áááēáááēááąáŦááēááŊááˇáēááá¯áááēáááˇáēáááēáááēááá¯áĄááēáááēá
áááąáŦááģááē -> áááēáááēááģáŦḠ-> ááá¯áážáąáŦááēááąá¸ -> áĄááŦáĄááŊááēááŦáááŊá˛ááģáŦá¸ááá¯áˇ ááŊáŦá¸ááĢá ááģáŊááēá¯ááēááá¯áˇáááē á ááēá¸ááģááēá¸ááģáŦá¸áĄáŦá¸áá¯áļá¸ááᯠááģááēááŧáŽá¸ á ááēá¸áááēá¸ááģááēáá áēáá¯áááēá¸ááᯠWildcard * ááŧááˇáē ááááēá¸áážáááąá¸áááˇáē áĄáááēá¸ááášáááŧááˇáē áĄáá¯áļá¸ááŧá¯áá°ááģáŦá¸áĄááŊááēááŦ ááŊááēá¸áĄáŦá¸ááąá¸ááŧáŽá¸ ááąáĢááēá¸á ááēá¸ááá¯ááēááŊááˇáēáážááááēá á¤á ááēá¸ááģááēá¸áááē á¤áááąáŦááģááēáážá áēáá¯áá¯áļá¸áážááˇáē á¤áááąáŦááģááēááá¯ááēááá¯ááēáááˇáēáĄááŊá˛áˇá áĄáá¯áļá¸ááŧá¯áá°áĄáŦá¸áá¯áļá¸áĄááŊááē áĄáá¯ááēáá¯ááēáááēááŧá áēáááēá
- ááááēá¸ááááēá¸áá°áĄááģáŦá¸áĄááŧáŦá¸áážáááĢáá áĄááąáŦááēá¸áá¯áļá¸ááŧáąáážááēá¸ááģááēáážáŦ áááąáŦááģááēááá¯áˇáááēááąáŦááēááŊááˇáēááá¯áá°áĄááááˇáēáááēáááēááŧá
áēáááēá
áááąáŦááģááē -> áááēáááēááģáŦḠ-> áĄááŊáąááŊáą -> ááŧááēááá¯ááēáážá¯á áááąáŦááģááēáĄááēášááĢáááēááģáŦá¸á ááŊááˇáēááŧá¯ááģááēááģáŦá¸ááᯠááŊáŦá¸ááŧáŽá¸ áááąáŦááģááēááŧááēááá¯ááēá áŊááēá¸ááᯠáááēáážááēááĢá ááá¯ááēááá¯ááē.
ááģáŊááēá¯ááēáááē ááģáŊááēá¯ááēáááá¯ááēááá¯ááē GitLab Runner ááá¯áĄáá¯áļá¸ááŧá¯ááŧáŽá¸ repository ááá¯ááŧáąáŦááēá¸áá˛áááē áá áēáĻá¸áááēá¸ááŦ áááēááąáŦááēááŊááˇáēáážáááąáŦááŧáąáŦááˇáē ááģáŊááēá¯ááēááŊááē áĄááģáŦá¸áá°áážáŦ áĄáá¯áļá¸ááŧá¯ááá¯ááēááąáŦ áááąáŦááģááēáá áēáá¯áážááááēá áĄáážááēááąáŦáˇá áĄááģáŦá¸áá°áážáŦ ááá¯ááēááá¯ááēá¸áážááēáááēá¸ááģáŦá¸ááŊááē ááá¯ááēááąá¸ááá¯ááēááŦáĄááģááēáĄáááēááģáŦá¸ááá¯ááŧááááē ááģáŊááēá¯ááēááĄááģáá¯á¸á áŽá¸ááŊáŦá¸ááá¯ááēááĢá - ááá¯áážáąáŦááēáážá¯áĄáŦḠááŧáąáŦááēá¸áá˛ááŧááēá¸áĄááŊááē á
ááēá¸ááģááēá¸ááģáŦḠáááēá¸ááģááēááŧááēá¸á
áááąáŦááģááē -> Settings -> Repository -> Push Rules ááá¯ááŊáŦá¸ááŧáŽá¸ Committer áááˇáēáááēááģááēááᯠáááēáážááēááĢá á áŦááąá¸áá°áááē GitLab áĄáá¯áļá¸ááŧá¯áá°áĄááļááģáŦḠáá¯ááēááá¯ááē á á áēááąá¸ááĢá áááēáááēáááēáááēḠáĄááŧáļááŧá¯ááĢáááēá áážááˇáē Reject unsigned commits áĄááļááᯠáááēáážááēááĢá - ááá¯áˇááąáŦááē áá¯ááēááąáŦááēá
ááŦááģáŦá¸ááᯠá
áááēáááē áĄá
ááģáá¯á¸áá
áēáá¯ááᯠáááēáážááēáááē ááá¯áĄááēáááēá
áááąáŦááģááē -> áááēáááēááģáŦḠ-> CI / CD -> ááá¯ááēááá¯ááēá¸áĄá ááģáá¯á¸áážá¯ááģáŦá¸ááá¯áˇ ááŊáŦá¸ááŧáŽá¸ áĄá ááģáá¯á¸-ááá¯áááēáĄáá áēáá áēáᯠáááēááŽá¸ááĢá
á¤ááá¯áááēááᯠáááąáŦááģááēáĄá¯ááēá á¯áá áēáá¯áĄááŊááē ááááēá¸áážááēááģáŦá¸á ááąáá¯ááģááŊá˛áˇá ááēá¸áá¯áļááŊááē ááģááēááģááēá¸áááˇáēááá¯ááēáááēá
group -> Settings -> CI / CD -> Variables ááá¯áˇááŊáŦá¸á variable ááá¯áááˇáēááĢáDEPLOY_TOKENáááēááá¯á¸áážá trigger-token áážááˇáēáĄáá°á
GitLab áĄááŧáąá¸áááŦá¸
áááˇáēááá¯ááēááá¯ááē (Specific) áážááˇáē áĄááģáŦá¸áá°áážáŦ (ááģážááąááŦá¸ááąáŦ) áĄááŧáąá¸áááŦá¸ááᯠáĄáá¯áļá¸ááŧá¯á ááŧááˇáēááģááēáá¯ááēááąáŦááēáááˇáē áá¯ááēááąáŦááēá ááŦááģáŦá¸ááᯠáá¯ááēááąáŦááēáááēáĄááŊááē ááŊá˛áˇá ááēá¸áážá¯áá¯áļá áļááᯠá¤ááášáááŊááē ááąáŦáēááŧááŦá¸áááēá
áááēáááēáážááēáážááē áĄááŧáąá¸áááŦá¸
ááááá¯áļá¸áĄááąáá˛áˇ áĄáááēááŧáąáááēá ââááŧááēáááēá á
áģáąá¸ááąáĢáááēá ááŦááŧáąáŦááˇáēáá˛ááá¯ááąáŦᡠááá¯ááˇáēááá¯ááēááá¯ááē áĄááŧáąá¸áááŦá¸ááŊáąááᯠáá¯áļá¸áááēá
áĄááŧáąá¸áááŦá¸áĄááŊááēá CPU 1á 2 GB RAMá 20 GB HDD ááĢááąáŦ Linux VDS ááᯠáĄááŧáļááŧá¯ááĢáááēá áá¯ááēááąá¸ááąáŦá
áģáąá¸áážá¯ááēá¸áážáŦ áá
áēáážá
áēááģážááē ~3000âŊ ááŧá
áēáááēá
ááĢáˇáĄááŧáąá¸áááŦá¸
áĄááŧáąá¸áááŦá¸áĄááŊááē ááģáŊááēá¯ááēáááē VDS 4 CPUá 4 GB RAM á 50 GB SSD ááᯠáá°áá˛áˇáááēá ~11000âŊ áá¯ááēááģááŧáŽá¸ áááēááąáŦáˇááž ááąáŦááēáááááĢáá°á¸á
á
á¯á
á¯ááąáĢááēḠá
ááē á áá¯áļá¸áážááááēá Aruba ááŊááē 7 áážááˇáē 5 ihor á
áĄá˛ááŽááąáŦᡠáĄááŧáąá¸áááŦá¸áážááááēá ááᯠááģáŊááēá¯ááēááá¯áˇ áááēá¸ááᯠconfigure áá¯ááēááĢáááēá
SSH áážáá
áēáááˇáē á
ááēááá¯áˇááŊáŦá¸á java, git, maven, gnupg2 ááᯠinstall áá¯ááēááĢá
gitlab runner ááᯠáááˇáēááŊááēá¸ááŧááēá¸á
- áĄááŊá˛áˇáĄáá
áēáá
áēáá¯áááēááŽá¸ááĢá
runnersudo groupadd runner - maven áááēáážáēáĄááŊááē áááēá¸ááŊážááēáá
áēáá¯áááēááŽá¸ááŧáŽá¸ áĄááŊá˛áˇááŊááˇáēááŧá¯ááģááēááģáŦá¸ááᯠáááēáážááēááĢá
runner
á ááēáá áēáá¯áļá¸ááŊááē áĄááŧáąá¸áááŦá¸áĄááģáŦá¸áĄááŧáŦá¸ááᯠáááēáááēáááē áĄá áŽáĄá ááēááážáááĢá á¤áĄáážááēááᯠááģáąáŦáēááŊáŦá¸ááá¯ááēáááēámkdir -p /usr/cache/.m2/repository chown -R :runner /usr/cache chmod -R 770 /usr/cache - áĄáá¯áļá¸ááŧá¯áá°áááēááŽá¸ááĢá
gitlab-deployeráážááˇáēáĄááŊá˛áˇááá¯áˇáááˇáēááĢárunneruseradd -m -d /home/gitlab-deployer gitlab-deployer usermod -a -G runner gitlab-deployer - ááá¯ááēááá¯áˇáááˇáēááĢá
/etc/ssh/sshd_configááąáŦááēáá áēááŧáąáŦááēá¸AllowUsers root@* gitlab-deployer@127.0.0.1 - ááŧááēááŊááˇáēááĢá
sshdsystemctl restart sshd - áĄáá¯áļá¸ááŧá¯áá°áĄááŊááē á
ááŦá¸áážááēáá
áēáᯠáááēáážááēááŧááēá¸á
gitlab-deployer(Localhost áĄááŊááē áááˇáēáááēááģááēáá áēáᯠáážáááąáŦááŧáąáŦááˇáē ááá¯á¸áážááēá¸ááá¯ááēááĢáááēá)passwd gitlab-deployer - GitLab Runner ááᯠáááˇáēááŊááēá¸ááĢ (Linux xáá-áá)
sudo wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64 sudo chmod +x /usr/local/bin/gitlab-runner ln -s /usr/local/bin/gitlab-runner /etc/alternatives/gitlab-runner ln -s /etc/alternatives/gitlab-runner /usr/bin/gitlab-runner - gitlab.com -> deploy-project -> Settings -> CI/CD -> Runners -> Specific Runners ááá¯áˇááŊáŦá¸á áážááēáá¯áļáááēááŦá¸ááąáŦ ááá¯áááēááᯠáá°á¸áá°ááĢá
ááģááēáážáŦááŧááē
- áĄááŧáąá¸áááŦḠáážááēáá¯áļáááēááŧááēá¸á
gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml
ááŧá áēá ááē
Runtime platform arch=amd64 os=linux pid=17594 revision=3001a600 version=11.10.0
Running in system-mode.
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
https://gitlab.com/
Please enter the gitlab-ci token for this runner:
REGISTRATION_TOKEN
Please enter the gitlab-ci description for this runner:
[ih1174328.vds.myihor.ru]: Deploy Runner
Please enter the gitlab-ci tags for this runner (comma separated):
deploy
Registering runner... succeeded runner=ZvKdjJhx
Please enter the executor: docker-ssh, parallels, virtualbox, docker-ssh+machine, kubernetes, docker, ssh, docker+machine, shell:
shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!- áĄááŧáąá¸áááŦá¸á áŦáááēá¸ááŊááēá¸ááŧáŽá¸ááŧáąáŦááēḠá á áēááąá¸ááĢáááēá gitlab.com -> deploy-project -> áááēáááēááģáŦḠ-> CI/CD -> Runners -> Specific Runners -> Runners ááģáŦá¸ááᯠá¤áááąáŦááģááēáĄááŊááē activated
ááģááēáážáŦááŧááē
- áááˇáēááĢ ááŽá¸ááŧáŦḠáááēááąáŦááēáážá¯
/etc/systemd/system/gitlab-deployer.service[Unit] Description=GitLab Deploy Runner After=syslog.target network.target ConditionFileIsExecutable=/usr/local/bin/gitlab-runner [Service] StartLimitInterval=5 StartLimitBurst=10 ExecStart=/usr/local/bin/gitlab-runner "run" "--working-directory" "/home/gitlab-deployer" "--config" "/etc/gitlab-runner/gitlab-deployer-config.toml" "--service" "gitlab-deployer" "--syslog" "--user" "gitlab-deployer" Restart=always RestartSec=120 [Install] WantedBy=multi-user.target - áááēááąáŦááēáážá¯ááᯠá
ááá¯ááēááĄáąáŦááēá
systemctl enable gitlab-deployer.service systemctl start gitlab-deployer.service systemctl status gitlab-deployer.service - áĄááŧáąá¸áááŦá¸á ááŧáąá¸ááąááŦááᯠá á áēááąá¸áááēá
ááá°ááŦ
GPG ááąáŦáˇááģáŦá¸áá¯ááēááąá¸ááŧááēá¸á
- áá°ááŽááąáŦá
ááēáážáĄáá¯áļá¸ááŧá¯áá°áĄáąáŦááēáážá ssh áážááááˇáēááģáŊááēá¯ááēááá¯áˇáááēááąáŦááēáááēá
gitlab-deployer(áááēá¸áááē GPG ááąáŦáˇááá¯áááēááŽá¸áááēáĄááŊááē áĄááąá¸ááŧáŽá¸áááē)ssh gitlab-deployer@127.0.0.1 - ááģáŊááēá¯ááēááá¯áˇáááē ááąá¸ááŊááēá¸ááģáŦá¸ááá¯ááŧáąááá¯ááŧááēá¸ááŧááˇáē ááąáŦáˇáá
áēáá¯áá¯ááēááąá¸ááĢáááēá ááá¯ááˇáēááŦáááēáá˛áˇ áĄáŽá¸ááąá¸ááēááᯠáá¯áļá¸áááēá
ááąáŦáˇáĄááŊááē á ááŦá¸áážááēááᯠááąááģáŦáááēáážááēááĢá áá ášá ááēá¸ááģáŦá¸ááᯠá¤ááąáŦáˇááŧááˇáē áááēáážááēááąá¸ááá¯á¸ááĢáááēágpg --gen-key - áááēá¸á
á
áēááąá¸
gpg --list-keys -a /home/gitlab-deployer/.gnupg/pubring.gpg ---------------------------------------- pub 4096R/00000000 2019-04-19 uid Petruha Petrov <pp@example.com> sub 4096R/11111111 2019-04-19 - ááģáŊááēá¯ááēááá¯áˇá áĄááģáŦá¸áá°áážáŦááąáŦáˇááᯠááąáŦáˇááŦááŦááá¯áˇ áĄááēáá¯ááēáá¯ááēááŧááēá¸á
gpg --keyserver keys.gnupg.net --send-key 00000000 gpg: sending key 00000000 to hkp server keys.gnupg.net
Maven ááᯠá áá áēáááˇáēááŊááēá¸ááŧááēá¸á
- áĄáá¯áļá¸ááŧá¯áá°áĄááŧá
áē áĄááąáŦááˇáēáááēááĢá
gitlab-deployersu gitlab-deployer - maven áááēá¸ááŊážááēáá
áēáá¯áááēááŽá¸ááĢá repository áážááˇáē cache ááá¯áˇáááˇáēááē (áĄáážáŦá¸ááá¯ááēááĢáážááˇáē)
á ááēáá áēáá¯áļá¸ááŊááē áĄááŧáąá¸áááŦá¸áĄááģáŦá¸áĄááŧáŦá¸ááᯠáááēáááēáááē áĄá áŽáĄá ááēááážáááĢá á¤áĄáážááēááᯠááģáąáŦáēááŊáŦá¸ááá¯ááēáááēámkdir -p ~/.m2/repository ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository - ááŦá
ááŦááŽá¸áá
áēáá¯áááēááŽá¸ááĢá
mvn --encrypt-master-password password {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=} - ~/.m2/settings-security.xml ááá¯ááēáá
áēáᯠáááēááŽá¸ááĢá
<settingsSecurity> <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master> </settingsSecurity> - Sonatype áĄááąáŦááˇáēáĄááŊááē á
ááŦá¸áážááēááᯠáá¯ááēáážááēááŧááēá¸á
mvn --encrypt-password SONATYPE_PASSWORD {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J} - ~/.m2/settings.xml ááá¯ááēáá
áēáᯠáááēááŽá¸ááĢá
<settings> <profiles> <profile> <id>env</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <gpg.passphrase>GPG_SECRET_KEY_PASSPHRASE</gpg.passphrase> </properties> </profile> </profiles> <servers> <server> <id>sonatype</id> <username>SONATYPE_USERNAME</username> <password>{98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}</password> </server> </servers> </settings>
áááēáážáŦáá˛á
GPG_SECRET_KEY_PASSHRASE - GPG ááąáŦáˇáĄááŊááē á
ááŦá¸áážááē
SONATYPE_USERNAME â sonatype áĄááąáŦááˇáē áĄááąáŦááˇáēáááēááĢá
áááēá¸áááē áĄááŧáąá¸áááŦá¸á áááēáááēáážá¯áĄáŦḠáĄááŧáŽá¸áááēááŧáŽá¸ áĄááá¯ááēá¸ááá¯áˇ áááēáááēáá¯ááēááąáŦááēááá¯ááēáááēá
Shared Runner ááĢá
GPG ááąáŦáˇááģáŦá¸áá¯ááēááąá¸ááŧááēá¸á
- ááááĻá¸á
áŊáŦá áááēáááē GPG ááąáŦáˇááá¯áááēááŽá¸áááēááá¯áĄááēáááēá ááŽááá¯áá¯ááēááá¯áˇ gnupg ááᯠinstall áá¯ááēááĢá
yum install -y gnupg - ááģáŊááēá¯ááēááá¯áˇáááē ááąá¸ááŊááēá¸ááģáŦá¸ááá¯ááŧáąááá¯ááŧááēá¸ááŧááˇáē ááąáŦáˇáá
áēáá¯áá¯ááēááąá¸ááĢáááēá ááá¯ááˇáēááŦáááēáá˛áˇ áĄáŽá¸ááąá¸ááēááᯠáá¯áļá¸áááēá ááąáŦáˇáĄááŊááē á
ááŦá¸áážááēááᯠááąááģáŦáááēáážááēááĢá
gpg --gen-key - ááąáŦáˇááąáĢáēááŊááē áĄááģááēáĄáááēááᯠááŧáááŧááēá¸á
gpg --list-keys -a pub rsa3072 2019-04-24 [SC] [expires: 2021-04-23] 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 uid [ultimate] tttemp <temp@temp.temp> sub rsa3072 2019-04-24 [E] [expires: none] - ááģáŊááēá¯ááēááá¯áˇá áĄááģáŦá¸áá°áážáŦááąáŦáˇááᯠááąáŦáˇááŦááŦááá¯áˇ áĄááēáá¯ááēáá¯ááēááŧááēá¸á
gpg --keyserver keys.gnupg.net --send-key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 gpg: sending key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 to hkp server keys.gnupg.net - ááģáŊááēá¯ááēááá¯áˇáááē ááŽá¸áááˇáēááąáŦáˇááᯠááážáááĢáááēá
gpg --export-secret-keys --armor 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 -----BEGIN PGP PRIVATE KEY BLOCK----- lQWGBFzAqp8BDADN41CPwJ/gQwiKEbyA902DKw/WSB1AvZQvV/ZFV77xGeG4K7k5 ... =2Wd2 -----END PGP PRIVATE KEY BLOCK----- - áááąáŦááģááēáááēáááēááģáŦḠ-> áááēáááēááģáŦḠ-> CI / CD -> Variables ááá¯áˇááŊáŦá¸ááŦ ááŽá¸áááˇáēááŽá¸ááᯠááááēá¸áážááēáá
áēáá¯ááŊááē ááááēá¸áááēá¸ááĢá
GPG_SECRET_KEY
Maven ááᯠá áá áēáááˇáēááŊááēá¸ááŧááēá¸á
- ááŦá
ááŦááŽá¸áá
áēáá¯áááēááŽá¸ááĢá
mvn --encrypt-master-password password {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=} - áááąáŦááģááēáááēáááēááģáŦḠ-> áááēáááēááģáŦḠ-> CI / CD -> Variables ááá¯áˇááŊáŦá¸ááŦ variable ááŊááēááááēá¸áááēá¸ááĢá
SETTINGS_SECURITY_XMLáĄáąáŦááēááĢá áŦááŧáąáŦááēá¸ááģáŦá¸<settingsSecurity> <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master> </settingsSecurity> - Sonatype áĄááąáŦááˇáēáĄááŊááē á
ááŦá¸áážááēááᯠáá¯ááēáážááēááŧááēá¸á
mvn --encrypt-password SONATYPE_PASSWORD {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J} - áááąáŦááģááēáááēáááēááģáŦḠ-> áááēáááēááģáŦḠ-> CI / CD -> Variables ááá¯áˇááŊáŦá¸ááŦ variable ááŊááēááááēá¸áááēá¸ááĢá
SETTINGS_XMLáĄáąáŦááēááĢá áŦááŧáąáŦááēá¸ááģáŦá¸<settings> <profiles> <profile> <id>env</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <gpg.passphrase>GPG_SECRET_KEY_PASSPHRASE</gpg.passphrase> </properties> </profile> </profiles> <servers> <server> <id>sonatype</id> <username>sonatype_username</username> <password>{98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}</password> </server> </servers> </settings>
áááēáážáŦáá˛á
GPG_SECRET_KEY_PASSHRASE - GPG ááąáŦáˇáĄááŊááē á
ááŦá¸áážááē
SONATYPE_USERNAME â sonatype áĄááąáŦááˇáē áĄááąáŦááˇáēáááēááĢá
docker áá¯áļáĄáŦḠáĄáá¯áļá¸ááŧá¯ááĢá
- ááá¯áĄááēááąáŦ Java ááŦá¸áážááēá¸ááŧááˇáē áá¯ááēááąáŦááēá
ááŦááģáŦá¸ááᯠááŧááˇáēááģááēáá¯ááēááąáŦááēáááē ááģážááģážáá ááá¯á¸áážááēá¸ááąáŦ Dockerfile áá
áēáá¯ááᯠáááēááŽá¸ááĢáááēá áĄáąáŦááēááŊááē alpine áĨáááŦáá
áēáá¯ááŧá
áēáááēá
FROM java:8u111-jdk-alpine RUN apk add gnupg maven git --update-cache --repository http://dl-4.alpinelinux.org/alpine/edge/community/ --allow-untrusted && mkdir ~/.m2/ - áááˇáēáááąáŦááģááēáĄááŊááē ááŊááēááááēááŦáá
áēáá¯ááᯠáááēáááēááŧááēá¸á
docker build -t registry.gitlab.com/group/deploy . - ááģáŊááēá¯ááēááá¯áˇáááē á
á
áēáážááēááŧáąáŦááēá¸áĄááąáŦááēáĄááŦá¸ááŧááŧáŽá¸ ááŊááēááááēááŦááᯠáážááēáá¯áļáááēááŧááēá¸ááá¯áˇ áááēááĢáááēá
docker login -u USER -p PASSWORD registry.gitlab.com docker push registry.gitlab.com/group/deploy
GitLab CI
áááąáŦááģááēááᯠáĄáá¯áļá¸ááģááĢá
deploy áááąáŦááģááēá root ááŊááē .gitlab-ci.yml ááá¯ááēááᯠáááˇáēááĢá
ááŦááēááŊážááēá¸áááē áĄááŧááēáĄáážááēááŽá¸áááˇáē ááŧááˇáēááģááēáá¯ááēááąáŦááēá
ááŦ áážá
áēáá¯ááᯠáááēááŧáááēá Specific Runner ááá¯áˇááá¯ááē Shared Runner áĄááŽá¸ááŽá¸á
.gitlab-ci.yml
stages:
- deploy
Specific Runner:
extends: .java_deploy_template
# ĐадаŅа ĐąŅĐ´ĐĩŅ Đ˛ŅĐŋĐžĐģĐŊŅŅŅŅŅ ĐŊа ваŅĐĩĐŧ shell-ŅаĐŊĐŊĐĩŅĐĩ
tags:
- deploy
Shared Runner:
extends: .java_deploy_template
# ĐадаŅа ĐąŅĐ´ĐĩŅ Đ˛ŅĐŋĐžĐģĐŊŅŅŅŅŅ ĐŊа ĐŋŅĐąĐģиŅĐŊĐžĐŧ docker-ŅаĐŊĐŊĐĩŅĐĩ
tags:
- docker
# ĐĐąŅаС иС ŅаСдĐĩĐģа GitLab Runner -> Shared Runner -> Docker
image: registry.gitlab.com/group/deploy-project:latest
before_script:
# ĐĐŧĐŋĐžŅŅиŅŅĐĩĐŧ GPG ĐēĐģŅŅ
- printf "${GPG_SECRET_KEY}" | gpg --batch --import
# ĐĄĐžŅ
ŅаĐŊŅĐĩĐŧ maven ĐēĐžĐŊŅĐ¸ĐŗŅŅаŅиŅ
- printf "${SETTINGS_SECURITY_XML}" > ~/.m2/settings-security.xml
- printf "${SETTINGS_XML}" > ~/.m2/settings.xml
.java_deploy_template:
stage: deploy
# ĐадаŅа ŅŅайОŅаĐĩŅ ĐŋĐž ŅŅĐ¸ĐŗĐŗĐĩŅŅ, ĐĩŅĐģи ĐŋĐĩŅĐĩдаĐŊа ĐŋĐĩŅĐĩĐŧĐĩĐŊĐŊĐ°Ņ DEPLOY ŅĐž СĐŊаŅĐĩĐŊиĐĩĐŧ java
only:
variables:
- $DEPLOY == "java"
variables:
# ĐžŅĐēĐģŅŅаĐĩĐŧ ĐēĐģĐžĐŊиŅОваĐŊиĐĩ ŅĐĩĐēŅŅĐĩĐŗĐž ĐŋŅĐžĐĩĐēŅа
GIT_STRATEGY: none
script:
# ĐŅĐĩĐ´ĐžŅŅавĐģŅĐĩĐŧ вОСĐŧĐžĐļĐŊĐžŅŅŅ Ņ
ŅаĐŊĐĩĐŊĐ¸Ņ ĐŋаŅĐžĐģŅ Đ˛ ĐŊĐĩСаŅиŅŅОваĐŊĐŊĐžĐŧ видĐĩ
- git config --global credential.helper store
# ĐĄĐžŅ
ŅаĐŊŅĐĩĐŧ вŅĐĩĐŧĐĩĐŊĐŊŅĐĩ ĐēŅĐĩĐ´Ņ ĐŋĐžĐģŅСОваŅĐĩĐģŅ gitlab-ci-token
# ĐĸĐžĐēĐĩĐŊ ŅайОŅаĐĩŅ Đ´ĐģŅ Đ˛ŅĐĩŅ
ĐŋŅĐąĐģиŅĐŊŅŅ
ĐŋŅĐžĐĩĐēŅОв gitlab.com и Đ´ĐģŅ ĐŋŅĐžĐĩĐēŅОв ĐŗŅŅĐŋĐŋŅ
- echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com" >> ~/.git-credentials
# ĐĐžĐģĐŊĐžŅŅŅŅ ŅиŅŅиĐŧ ŅĐĩĐēŅŅŅŅ Đ´Đ¸ŅĐĩĐēŅĐžŅиŅ
- rm -rf .* *
# ĐĐģĐžĐŊиŅŅĐĩĐŧ ĐŋŅĐžĐĩĐēŅ ĐēĐžŅĐžŅŅĐš, ĐąŅĐ´ĐĩĐŧ Đ´ĐĩĐŋĐģОиŅŅ Đ˛ Sonatype Nexus
- git clone ${DEPLOY_CI_REPOSITORY_URL} .
# ĐĐĩŅĐĩĐēĐģŅŅаĐĩĐŧŅŅ ĐŊа ĐŊŅĐļĐŊŅĐš ĐēĐžĐŧĐŧиŅ
- git checkout ${DEPLOY_CI_COMMIT_SHA} -f
# ĐŅĐģи Ņ
ĐžŅŅ ĐžĐ´Đ¸ĐŊ pom.xml ŅОдĐĩŅĐļĐ¸Ņ ĐŋаŅаĐŧĐĩŅŅ autoReleaseAfterClose ваĐģиĐŧ ŅйОŅĐēŅ.
# Đ ĐŋŅĐžŅивĐŊĐžĐŧ ŅĐģŅŅаĐĩ ĐĩŅŅŅ ŅиŅĐē СаĐģиŅŅ ŅŅŅŅĐĩ аŅŅĐĩŅаĐēŅŅ Đ˛ maven central
- >
for pom in $(find . -name pom.xml); do
if [[ $(grep -q autoReleaseAfterClose "$pom" && echo $?) == 0 ]]; then
echo "File $pom contains prohibited setting: <autoReleaseAfterClose>";
exit 1;
fi;
done
# ĐŅĐģи ĐŋаŅаĐŧĐĩŅŅ DEPLOY_CI_COMMIT_TAG ĐŋŅŅŅОК, ŅĐž ĐŋŅиĐŊŅдиŅĐĩĐģŅĐŊĐž ŅŅавиĐŧ SNAPSHOT-вĐĩŅŅиŅ
- >
if [[ "${DEPLOY_CI_COMMIT_TAG}" != "" ]]; then
mvn versions:set -DnewVersion=${DEPLOY_CI_COMMIT_TAG}
else
VERSION=$(mvn -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec)
if [[ "${VERSION}" == *-SNAPSHOT ]]; then
mvn versions:set -DnewVersion=${VERSION}
else
mvn versions:set -DnewVersion=${VERSION}-SNAPSHOT
fi
fi
# ĐаĐŋŅŅĐēаĐĩĐŧ СадаŅŅ ĐŊа ŅйОŅĐēŅ Đ¸ Đ´ĐĩĐŋĐģОК аŅŅĐĩŅаĐēŅОв
- mvn clean deploy -DskipTests=trueJava áááąáŦááģááē
áĄááģáŦá¸áá°áážáŦ ááá¯áážáąáŦááēááŦááģáŦá¸ááá¯áˇ áĄááēáá¯ááēáá¯ááēááŦá¸ááááˇáē java áááąáŦááģááēááģáŦá¸ááŊááēá Release áážááˇáē Snapshot ááŦá¸áážááēá¸ááģáŦá¸ááᯠááąáĢááēá¸áá¯ááēáá¯ááēáááē áĄáááˇáē á áááˇáē áááēáááˇáēáááē ááá¯áĄááēáááēá
.gitlab-ci.yml
stages:
- build
- test
- verify
- deploy
<...>
Release:
extends: .trigger_deploy
# ĐаĐŋŅŅĐēаŅŅ ĐˇĐ°Đ´Đ°ŅŅ ŅĐžĐģŅĐēĐž Đŋo ŅĐĩĐŗŅ.
only:
- tags
Snapshot:
extends: .trigger_deploy
# ĐаĐŋŅŅĐēаĐĩĐŧ СадаŅŅ ĐŊа ĐŋŅĐąĐģиĐēаŅĐ¸Ņ SNAPSHOT вĐĩŅŅии вŅŅŅĐŊŅŅ
when: manual
# ĐĐĩ СаĐŋŅŅĐēаŅŅ ĐˇĐ°Đ´Đ°ŅŅ, ĐĩŅĐģи ĐŋŅĐžŅŅавĐģĐĩĐŊ ŅĐĩĐŗ.
except:
- tags
.trigger_deploy:
stage: deploy
variables:
# ĐŅĐēĐģŅŅаĐĩĐŧ ĐēĐģĐžĐŊиŅОваĐŊиĐĩ ŅĐĩĐēŅŅĐĩĐŗĐž ĐŋŅĐžĐĩĐēŅа
GIT_STRATEGY: none
# ĐĄŅŅĐģĐēа ĐŊа ŅŅĐ¸ĐŗĐŗĐĩŅ deploy-СадаŅи
URL: "https://gitlab.com/api/v4/projects/<deploy project ID>/trigger/pipeline"
# ĐĐĩŅĐĩĐŧĐĩĐŊĐŊŅĐĩ deploy-СадаŅи
POST_DATA: "
token=${DEPLOY_TOKEN}&
ref=master&
variables[DEPLOY]=${DEPLOY}&
variables[DEPLOY_CI_REPOSITORY_URL]=${CI_REPOSITORY_URL}&
variables[DEPLOY_CI_PROJECT_NAME]=${CI_PROJECT_NAME}&
variables[DEPLOY_CI_COMMIT_SHA]=${CI_COMMIT_SHA}&
variables[DEPLOY_CI_COMMIT_TAG]=${CI_COMMIT_TAG}
"
script:
# ĐĐĩ иŅĐŋĐžĐģŅСŅŅ cURL, ŅаĐē ĐēаĐē Ņ ŅĐģĐ°ĐŗĐ°Đŧи --fail --show-error
# ĐžĐŊ ĐŊĐĩ вŅĐ˛ĐžĐ´Đ¸Ņ ŅĐĩĐģĐž ĐžŅвĐĩŅа, ĐĩŅĐģи HTTP ĐēОд 400 и йОĐģĐĩĐĩ
- wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}á¤ááŧáąáážááēá¸ááģááēááŊááēá ááģáŊááēá¯ááēáááē áĄáááēá¸áááēááá¯á java áááąáŦááģááēááģáŦá¸áĄááŊááē CI ááá°ááŦáá¯áļá áļáá áēáá¯ááᯠáĄáá¯áļá¸ááŧá¯áááē áá¯áļá¸ááŧááēáá˛áˇáááēá
ááá¯ááŧáŽá¸áĄááąá¸á áááē
ááŽá¸ááŧáŦá¸áááąáŦááģááēáá áēáá¯ááᯠáááēááŽá¸áá˛áˇáááēá java áááąáŦááģááēááģáŦá¸áĄááŊááē CI áá¯áļá áļáá áēáá¯ááᯠááŦá¸áážááá˛áˇáááēá .
common.yml
stages:
- build
- test
- verify
- deploy
variables:
SONAR_ARGS: "
-Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA}
-Dsonar.gitlab.ref_name=${CI_COMMIT_REF_NAME}
"
.build_java_project:
stage: build
tags:
- touchbit-shell
variables:
SKIP_TEST: "false"
script:
- mvn clean
- mvn package -DskipTests=${SKIP_TEST}
artifacts:
when: always
expire_in: 30 day
paths:
- "*/target/reports"
.build_sphinx_doc:
stage: build
tags:
- touchbit-shell
variables:
DOCKERFILE: .indirect/docs/Dockerfile
script:
- docker build --no-cache -t ${CI_PROJECT_NAME}/doc -f ${DOCKERFILE} .
.junit_module_test_run:
stage: test
tags:
- touchbit-shell
variables:
MODULE: ""
script:
- cd ${MODULE}
- mvn test
artifacts:
when: always
expire_in: 30 day
paths:
- "*/target/reports"
.junit_test_run:
stage: test
tags:
- touchbit-shell
script:
- mvn test
artifacts:
when: always
expire_in: 30 day
paths:
- "*/target/reports"
.sonar_review:
stage: verify
tags:
- touchbit-shell
dependencies: []
script:
- >
if [ "$CI_BUILD_REF_NAME" == "master" ]; then
mvn compile sonar:sonar -Dsonar.login=$SONAR_LOGIN $SONAR_ARGS
else
mvn compile sonar:sonar -Dsonar.login=$SONAR_LOGIN $SONAR_ARGS -Dsonar.analysis.mode=preview
fi
.trigger_deploy:
stage: deploy
tags:
- touchbit-shell
variables:
URL: "https://gitlab.com/api/v4/projects/10345765/trigger/pipeline"
POST_DATA: "
token=${DEPLOY_TOKEN}&
ref=master&
variables[DEPLOY]=${DEPLOY}&
variables[DEPLOY_CI_REPOSITORY_URL]=${CI_REPOSITORY_URL}&
variables[DEPLOY_CI_PROJECT_NAME]=${CI_PROJECT_NAME}&
variables[DEPLOY_CI_COMMIT_SHA]=${CI_COMMIT_SHA}&
variables[DEPLOY_CI_COMMIT_TAG]=${CI_COMMIT_TAG}
"
script:
- wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}
.trigger_release_deploy:
extends: .trigger_deploy
only:
- tags
.trigger_snapshot_deploy:
extends: .trigger_deploy
when: manual
except:
- tags
ááááēáĄááąáážááˇáēá java áááąáŦááģááēááģáŦá¸ááŊááē áááēá¸ááá¯áˇááá¯ááēááá¯ááēá .gitlab-ci.yml áááē áĄááŊááēááģá áēááģá áēááŧáŽá¸ á ááŦá¸áááŧáąáŦááá¯ááēá
.gitlab-ci.yml
include: https://gitlab.com/TouchBIT/gitlab-ci/raw/master/common.yml
Shields4J:
extends: .build_java_project
Sphinx doc:
extends: .build_sphinx_doc
variables:
DOCKERFILE: .docs/Dockerfile
Sonar review:
extends: .sonar_review
dependencies:
- Shields4J
Release:
extends: .trigger_release_deploy
Snapshot:
extends: .trigger_snapshot_deployPom.xml ááŊá˛áˇá ááēá¸áážá¯
á¤áĄááŧáąáŦááēá¸áĄááŦááᯠáĄááąá¸á
áááēááąáŦáēááŧááŦá¸áááēá в ááĢááŧáąáŦááˇáē Plugins áĄáá¯áļá¸ááŧá¯ááŧááēá¸áá˛áˇ ááŊá˛ááŧáŦá¸ááģááēáĄááģáá¯áˇááᯠááąáŦáēááŧááĢáááēá áááēááᯠááŊááēáá°ááŧáŽá¸ ááąáĢáˇááąáĢáˇááĢá¸ááĢḠáá¯áļá¸ááá¯ááēáá˛ááá¯ááŦááá¯áááēḠááŧáąáŦááŧááąá¸ááŊáŦá¸áážáŦááĢá nexus-staging-maven-plugináááˇáēáááąáŦááģááēáĄááŊááē ááááĄááąááŧááˇáē org.sonatype.oss:oss-parent ááᯠáĄáá¯áļá¸áááŧá¯ááá¯ááĢá ááá¯áˇááá¯ááē ááá¯áļá¸ááá¯ááēááģážááēá
maven-install-plugin
ááąáááá¯ááēááŦááá¯áážáąáŦááēáážá¯ááŊááē ááąáŦáēááģá°á¸ááģáŦá¸ááᯠáááˇáēááŊááēá¸ááĢá
áĄááŧáŦá¸áááąáŦááģááēááģáŦá¸áážá ááŧáąáážááēá¸ááģááēááģáŦá¸áĄáŦḠááąáááá¯ááēááŦ á
áá
á
áēááŧááēá¸áĄááŧááē checksum áá
áēáá¯áĄááŊááē áĄááŊááēáĄáá¯áļá¸áááēááĢáááēá
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-project</id>
<!-- ĐŅĐģи Ņ Đ˛Đ°Ņ ĐŧĐŊĐžĐŗĐžĐŧОдŅĐģŅĐŊŅĐš ĐŋŅĐžĐĩĐēŅ Ņ Đ´ĐĩĐŋĐģĐžĐĩĐŧ ŅОдиŅĐĩĐģŅŅĐēĐžĐŗĐž ĐŋĐžĐŧиĐēа -->
<phase>install</phase>
<!-- Đ¯Đ˛ĐŊĐž ŅĐēаСŅваĐĩĐŧ ŅаКĐģŅ Đ´ĐģŅ ĐģĐžĐēаĐģŅĐŊОК ŅŅŅаĐŊОвĐēи -->
<configuration>
<file>target/${project.artifactId}-${project.version}.jar</file>
```target/${project.artifactId}-${project.version}-sources.jar</sources>
<pomFile>dependency-reduced-pom.xml</pomFile>
<!-- ĐŅиĐŊŅдиŅĐĩĐģŅĐŊĐžĐĩ ОйĐŊОвĐģĐĩĐŊиĐĩ ĐŧĐĩŅадаĐŊĐŊŅŅ
ĐŋŅĐžĐĩĐēŅа -->
<updateReleaseInfo>true</updateReleaseInfo>
<!-- ĐĐžĐŊŅŅĐžĐģŅĐŊŅĐĩ ŅŅĐŧĐŧŅ Đ´ĐģŅ ĐŋŅОвĐĩŅĐēи ŅĐĩĐģĐžŅŅĐŊĐžŅŅи -->
<createChecksum>true</createChecksum>
</configuration>
</execution>
</executions>
</plugin>maven-javadoc-ááááēáĄááē
áááąáŦááģááēáĄááŊááē javadoc ááá¯áá¯ááēáá¯ááēááŧááēá¸á
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<!-- ĐĐĩĐŊĐĩŅаŅĐ¸Ņ javadoc Đ´ĐžĐģĐļĐŊа ĐąŅŅŅ ĐŋĐžŅĐģĐĩ ŅĐ°ĐˇŅ ĐŗĐĩĐŊĐĩŅаŅии ŅĐĩŅŅŅŅОв -->
<phase>prepare-package</phase>
<configuration>
<!-- ĐŅĐĩĐŊŅ ĐŋĐžĐŧĐžĐŗĐ°ĐĩŅ Đ˛ ĐŋŅĐąĐģиŅĐŊŅŅ
ĐŋŅĐžĐĩĐēŅаŅ
-->
<failOnError>true</failOnError>
<failOnWarnings>true</failOnWarnings>
<!-- ĐŖĐąĐ¸ŅаĐĩŅ ĐžŅийĐēŅ ĐŋОиŅĐēа Đ´ĐžĐēŅĐŧĐĩĐŊŅаŅии в target диŅĐĩĐēŅĐžŅии -->
<detectOfflineLinks>false</detectOfflineLinks>
</configuration>
</execution>
</executions>
</plugin>áááˇáēááŊááē java áááĢáááēáááˇáē module áá
áēáá¯áážáááĢá (áĨáááŦ áĄáááēá¸áĄááŧá
áēááģáŦá¸ááŦ)
ááĢáážááá¯ááē áá°áĄá javadoc ááᯠááááēááŽá¸ááģááēáá°á¸ááá¯áááē áá°ááŽááá¯ááēááĢá maven-jar-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>empty-javadoc-jar</id>
<phase>generate-resources</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>javadoc</classifier>
<classesDirectory>${basedir}/javadoc</classesDirectory>
</configuration>
</execution>
</executions>
</plugin>maven-gpg-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<executions>
<execution>
<id>sign-artifacts</id>
<!-- ХйОŅĐēа ĐąŅĐ´ĐĩŅ ĐŋадаŅŅ, ĐĩŅĐģи ĐžŅŅŅŅŅŅвŅĐĩŅ GPG ĐēĐģŅŅ -->
<!-- ĐОдĐŋиŅŅваĐĩĐŧ аŅŅĐĩŅаĐēŅŅ ŅĐžĐģŅĐēĐž ĐŊа ŅаСĐĩ deploy -->
<phase>deploy</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>nexus-staging-maven-plugin
ááŊá˛áˇá ááēá¸áážá¯-
<project>
<!-- ... -->
<build>
<plugins>
<!-- ... -->
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<serverId>sonatype</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<!-- ĐĐąĐŊОвĐģŅĐĩĐŧ ĐŧĐĩŅадаĐŊĐŊŅĐĩ, ŅŅĐžĐąŅ ĐŋĐžĐŧĐĩŅиŅŅ Đ°ŅŅĐĩŅаĐēŅ ĐēаĐē release -->
<!-- ĐĐĩ вĐģиŅĐĩŅ ĐŊа snapshot вĐĩŅŅии -->
<updateReleaseInfo>true</updateReleaseInfo>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<!-- ĐŅĐēĐģŅŅаĐĩĐŧ ĐŋĐģĐ°ĐŗĐ¸ĐŊ -->
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<distributionManagement>
<snapshotRepository>
<id>sonatype</id>
<name>Nexus Snapshot Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
<repository>
<id>sonatype</id>
<name>Nexus Release Repository</name>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
</project>áááˇáēááŊááē multi-module áááąáŦááģááēáá
áēáá¯áážáá ááá¯áážáąáŦááēáááēá¸ááá¯áˇ ááŽá¸ááŧáŦḠmodule áá
áēáá¯ááᯠáĄááēáá¯ááēáá¯ááēáááē áááá¯áĄááēááĢáá áááēáááˇáēáááē ááá¯áĄááēááĢáááēá nexus-staging-maven-plugin áĄááļáážááˇáēáĄáá° skipNexusStagingDeployMojo
<build>
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<configuration>
<skipNexusStagingDeployMojo>true</skipNexusStagingDeployMojo>
</configuration>
</plugin>
</plugins>
</build>ááąáĢááēá¸áá¯ááēáá¯ááēááŧáŽá¸ááąáŦááēá ááģážááēáá áēááŧááēááá¯ááēááģááē/áá¯ááēááąáážá¯ááŦá¸áážááēá¸ááģáŦá¸ááŊááē áááá¯ááēááĢáááēá
<repositories>
<repository>
<id>SonatypeNexus</id>
<url>https://oss.sonatype.org/content/groups/staging/</url>
<!-- ĐĐĩ ĐŊадО ŅĐēаСŅваŅŅ ŅĐģĐ°ĐŗĐ¸ snapshot/release Đ´ĐģŅ ŅĐĩĐŋОСиŅĐžŅĐ¸Ņ -->
</repository>
</repositories>ááá¯áĄáŦá¸ááŦááģááēááģáŦá¸
- nexus repository áážááˇáē áĄáá¯ááēáá¯ááēáááēáĄááŊááē áĄááŊááēááŧáŊááēáááąáŦ áááēá¸ááá¯ááēááģáŦá¸á
áŦáááēḠ(
mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin). - maven áááá¯ááá¯áˇ áĄááēáá¯ááēáááēááŧááēá¸áĄááŊááē áĄááá¯áĄááģáąáŦááēáá¯ááēááŊážááēáážá¯ááᯠá á áēááąá¸ááĢá
ááááē
SNAPSHOT ááŦá¸áážááēá¸ááᯠáá¯ááēááąááŧááēá¸á
áááąáŦááģááēáá áēáá¯áááēááąáŦááēááąáŦáĄááĢá SNAPSHOT ááŦá¸áážááēá¸ááᯠááģáááēáááēáááēáĄááŊááē áá¯ááēááąáŦááēá ááŦáá áēáá¯ááᯠááá¯ááēááá¯ááēá áááēáá¯ááēááąáŦááēááá¯ááēáááēá
á¤áá¯ááēáááēá¸ááᯠá áááēááąáŦáĄááĢá ááŧááˇáēááģááēáááąáŦááģááēáážá áááēááá¯ááēáááˇáēááŦáááēááᯠáĄá ááģáá¯á¸áááē ().
ááŧááēááąáŦááēááŦá¸ááąáŦ áážááēáááēá¸
Running with gitlab-runner 11.10.0 (3001a600)
on Deploy runner JSKWyxUw
Using Shell executor...
Running on ih1174328.vds.myihor.ru...
Skipping Git repository setup
Skipping Git checkout
Skipping Git submodules setup
$ rm -rf .* *
$ git config --global credential.helper store
$ echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com" >> ~/.git-credentials
$ git clone ${DEPLOY_CI_REPOSITORY_URL} .
Cloning into 'shields4j'...
$ git checkout ${DEPLOY_CI_COMMIT_SHA}
Note: checking out '850f86aa317194395c5387790da1350e437125a7'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
HEAD is now at 850f86a... skip deploy test-core
$ for pom in $(find . -name pom.xml); do # collapsed multi-line command
$ if [[ "${DEPLOY_CI_COMMIT_TAG}" != "" ]]; then # collapsed multi-line command
[INFO] Scanning for projects...
[INFO] Inspecting build with total of 4 modules...
[INFO] Installing Nexus Staging features:
[INFO] ... total of 4 executions of maven-deploy-plugin replaced with nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] Shields4J [pom]
[INFO] test-core [jar]
[INFO] Shields4J client [jar]
[INFO] TestNG listener [jar]
[INFO]
[INFO] --------------< org.touchbit.shields4j:shields4j-parent >---------------
[INFO] Building Shields4J 1.0.0 [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.5:set (default-cli) @ shields4j-parent ---
[INFO] Searching for local aggregator root...
[INFO] Local aggregation root: /home/gitlab-deployer/JSKWyxUw/0/TouchBIT/deploy/shields4j
[INFO] Processing change of org.touchbit.shields4j:shields4j-parent:1.0.0 -> 1.0.0-SNAPSHOT
[INFO] Processing org.touchbit.shields4j:shields4j-parent
[INFO] Updating project org.touchbit.shields4j:shields4j-parent
[INFO] from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO]
[INFO] Processing org.touchbit.shields4j:client
[INFO] Updating parent org.touchbit.shields4j:shields4j-parent
[INFO] from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO] Updating dependency org.touchbit.shields4j:test-core
[INFO] from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO]
[INFO] Processing org.touchbit.shields4j:test-core
[INFO] Updating parent org.touchbit.shields4j:shields4j-parent
[INFO] from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO]
[INFO] Processing org.touchbit.shields4j:testng
[INFO] Updating parent org.touchbit.shields4j:shields4j-parent
[INFO] from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO] Updating dependency org.touchbit.shields4j:client
[INFO] from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO] Updating dependency org.touchbit.shields4j:test-core
[INFO] from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] Shields4J 1.0.0 .................................... SUCCESS [ 0.992 s]
[INFO] test-core .......................................... SKIPPED
[INFO] Shields4J client ................................... SKIPPED
[INFO] TestNG listener 1.0.0 .............................. SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.483 s
[INFO] Finished at: 2019-04-21T02:40:42+03:00
[INFO] ------------------------------------------------------------------------
$ mvn clean deploy -DskipTests=${SKIP_TESTS}
[INFO] Scanning for projects...
[INFO] Inspecting build with total of 4 modules...
[INFO] Installing Nexus Staging features:
[INFO] ... total of 4 executions of maven-deploy-plugin replaced with nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] Shields4J [pom]
[INFO] test-core [jar]
[INFO] Shields4J client [jar]
[INFO] TestNG listener [jar]
[INFO]
[INFO] --------------< org.touchbit.shields4j:shields4j-parent >---------------
[INFO] Building Shields4J 1.0.0-SNAPSHOT [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
...
DELETED
...
[INFO] * Bulk deploy of locally gathered snapshot artifacts finished.
[INFO] Remote deploy finished with success.
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] Shields4J 1.0.0-SNAPSHOT ........................... SUCCESS [ 2.375 s]
[INFO] test-core .......................................... SUCCESS [ 3.929 s]
[INFO] Shields4J client ................................... SUCCESS [ 3.815 s]
[INFO] TestNG listener 1.0.0-SNAPSHOT ..................... SUCCESS [ 36.134 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 47.629 s
[INFO] Finished at: 2019-04-21T02:41:32+03:00
[INFO] ------------------------------------------------------------------------ááááēáĄááąááŧááˇáēá ááŦá¸áážááēá¸ááᯠNexus ááŊááēáááēááŦá¸áááēá .
ááģážááēáá áēááŧááē ááŦá¸áážááēá¸áĄáŦá¸áá¯áļá¸ááᯠáááēááá¯ááēáážá ááá¯áážáąáŦááēáážá¯ááž ááģááēááá¯ááēáááēá áááˇáēáĄááąáŦááˇáēáĄáąáŦááēááŊááēá
áá¯ááēááąáážá¯ááŦá¸áážááēá¸ááᯠáá¯ááēááąááŧááēá¸á
áááēááᯠáááˇáēááŊááēá¸ááąáŦáĄááĢá ááŧááˇáēááģááēáááąáŦááģááēáážá áááēááá¯ááēááŦáá¯ááēáááēá¸ááŦáááēáááē ááŧááˇáēááģááááˇáēááŦá¸áážááēá¸ááᯠnexus ááá¯áˇááąáĢááēá¸áá¯ááēáá¯ááēáááē áĄááá¯áĄááģáąáŦááē áĄá ááģáá¯á¸ááŊáŦá¸áááē ().
áĄááąáŦááēá¸áá¯áļá¸áĄááá¯ááēá¸áážáŦ áĄááŽá¸áááēáá¯ááēááŊážááēáážá¯áááē ááģáááēáááēáážá¯ááŊááē áĄááá¯áĄááģáąáŦááē áĄá ááģáá¯á¸ááąááŧááēḠááŧá áēáááēá
[INFO] Performing remote staging...
[INFO]
[INFO] * Remote staging into staging profile ID "9043b43f77dcc9"
[INFO] * Created staging repository with ID "orgtouchbit-1037".
[INFO] * Staging repository at https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1037
[INFO] * Uploading locally staged artifacts to profile org.touchbit
[INFO] * Upload of locally staged artifacts finished.
[INFO] * Closing staging repository with ID "orgtouchbit-1037".
Waiting for operation to complete...
.........
[INFO] Remote staged 1 repositories, finished with success.
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] Shields4J 1.0.0 .................................... SUCCESS [ 9.603 s]
[INFO] test-core .......................................... SUCCESS [ 3.419 s]
[INFO] Shields4J client ................................... SUCCESS [ 9.793 s]
[INFO] TestNG listener 1.0.0 .............................. SUCCESS [01:23 min]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:47 min
[INFO] Finished at: 2019-04-21T04:05:46+03:00
[INFO] ------------------------------------------------------------------------áá áēáá¯áá¯áážáŦá¸ááŊáŦá¸áááē áĄáá¯ááēá ááģáááēá¸ááąááĢáá˛á
[INFO] Performing remote staging...
[INFO]
[INFO] * Remote staging into staging profile ID "9043b43f77dcc9"
[INFO] * Created staging repository with ID "orgtouchbit-1038".
[INFO] * Staging repository at https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1038
[INFO] * Uploading locally staged artifacts to profile org.touchbit
[INFO] * Upload of locally staged artifacts finished.
[INFO] * Closing staging repository with ID "orgtouchbit-1038".
Waiting for operation to complete...
.......
[ERROR] Rule failure while trying to close staging repository with ID "orgtouchbit-1039".
[ERROR]
[ERROR] Nexus Staging Rules Failure Report
[ERROR] ==================================
[ERROR]
[ERROR] Repository "orgtouchbit-1039" failures
[ERROR] Rule "signature-staging" failures
[ERROR] * No public key: Key with id: (1f42b618d1cbe1b5) was not able to be located on <a href=http://keys.gnupg.net:11371/>http://keys.gnupg.net:11371/</a>. Upload your public key and try the operation again.
...
[ERROR] Cleaning up local stage directory after a Rule failure during close of staging repositories: [orgtouchbit-1039]
[ERROR] * Deleting context 9043b43f77dcc9.properties
[ERROR] Cleaning up remote stage repositories after a Rule failure during close of staging repositories: [orgtouchbit-1039]
[ERROR] * Dropping failed staging repository with ID "orgtouchbit-1039" (Rule failure during close of staging repositories: [orgtouchbit-1039]).
[ERROR] Remote staging finished with a failure: Staging rules failure!
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] Shields4J 1.0.0 .................................... SUCCESS [ 4.073 s]
[INFO] test-core .......................................... SUCCESS [ 2.788 s]
[INFO] Shields4J client ................................... SUCCESS [ 3.962 s]
[INFO] TestNG listener 1.0.0 .............................. FAILURE [01:07 min]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------ááá¯áˇááŧáąáŦááˇáē ááģáŊááēá¯ááēááá¯áˇáááē ááŊáąá¸ááģááēáážá¯áá áēáá¯ááŦ ááģááēááąáŦáˇáááēá á¤ááŦá¸áážááēá¸ááᯠááģááēáá áēááĢ ááá¯áˇááá¯ááē áá¯ááēááąáááēááŦá¸á
áá¯ááēááąááŧáŽá¸ááąáŦááē áĄááģáááēáĄáááēááŧáŦááąáŦáĄááĢááŊááē áá ášá ááēá¸ááģáŦḠáááēááŦáááēááŧá áēáááēá
ááŧááēááĄááŧáąáŦááēá¸áĄááŦ
maven áááē áĄááŧáŦá¸ááąáŦ áĄááģáŦá¸áá°áážáŦ ááá¯áážáąáŦááēááŦááģáŦá¸ááᯠáĄááŊážááēá¸ááááēá¸ááģáŦḠááŧá¯áá¯ááēááąá¸ááąáŦ áážáŦááŊáąááŊáąáˇáážááážá¯áá
áēáá¯ááŧá
áēáááēá
áááēá¸áááē ááģáŊááēá¯ááēá ááá¯áážáąáŦááēáážá¯ááąáŦááēá¸ááᯠááŊážááēá¸ááŦá¸ááąáŦááŧáąáŦááˇáē robots.txt ááᯠáááˇáēáá˛áˇááááēá
ááąáŦááēááģááē
ááĢááá¯áˇáážáŦ ááŦáážááá˛á
- ááŊáļáˇááŧáá¯á¸ááá¯á¸áááēáážá¯ááŦááŦá ááŦá¸áĄááģáá¯á¸ááģáá¯á¸áĄááŊááē artifacts ááģáŦá¸ááᯠáĄááģáŦá¸áá°áážáŦ ááá¯áážáąáŦááēááŦááģáŦá¸ááá¯áˇ áĄááēáá¯ááēáááēáááēáĄááŊááē CI áá¯ááēáááēá¸ááģáŦá¸á áŊáŦááᯠáááēáĄááąáŦááēáĄáááēááąáŦáēááá¯ááēáááˇáē ááŽá¸ááŧáŦá¸áĄáá¯áļá¸ááģáááąáŦááģááēáá áēáá¯á
- Deploy áááąáŦááģááēááᯠááŧááēááááēááąáŦááēá áŊááēáááēáážá¯ááž ááŽá¸ááŧáŦá¸ááŊá˛áá¯ááēááŦá¸ááŧáŽá¸ ááá¯ááēáážááēáážááˇáē ááááēá¸ááááēá¸áá° áĄáááēá¸ááášáááģáŦá¸ááŧááˇáē áĄáá¯áļá¸ááŧá¯áá°ááģáŦá¸ááŦ ááŧáąáŦááēá¸áá˛ááá¯ááēáááēá
- áá¯ááēááąáŦááēá ááŦááģáŦá¸ááᯠáĄáá¯áļá¸ááģáááēáĄááŊááēááŦ áá¯ááēááąáŦááēáááē "hot" cache ááĢááąáŦ ááŽá¸ááŧáŦḠááŽá¸ááŧáŦḠRunner áá áēáá¯á
- áĄááģáŦá¸áá°áážáŦ ááá¯áážáąáŦááēáážá¯ááŊááē ááģážááēáá áēááŧááēááá¯ááēááģááē/áá¯ááēááąáážá¯ááŦá¸áážááēá¸ááģáŦá¸ááᯠáá¯ááēááąááŧááēá¸á
- maven Central ááŊááē áá¯ááēááąáááē áĄáááēáááˇáēááŧá áēáážá¯ áĄááŊááē ááŊááēáážááááˇáēááŦá¸áážááēá¸ááᯠáĄááá¯áĄááģáąáŦááēá á áēááąá¸ááĢá
- maven áĄáááēááá¯ááēá¸áážá "ááŧááēá¸" ááŦá¸áážááēá¸ááģáŦá¸áĄááá¯áĄááģáąáŦááēáá¯ááēááąááŧááēá¸áážááŦááŊááēáážá¯á
- ááģážááēáá áēááŧááē ááŦá¸áážááēá¸ááģáŦá¸ááᯠ"ááá áēáážáááēááĢ" ááᯠáááēááąáŦááēááŧáŽá¸ áá¯ááēááąááĢá
- ááģážááēáá áēááŧááēááá¯ááēááģááē/áá¯ááēááŊážááēáážá¯ááŦá¸áážááēá¸ááģáŦá¸ááá°áááēáĄááŊááē áá áēáá¯áááēá¸ááąáŦ ááá¯áážáąáŦááēáá¯áļá
- Java áááąáŦááģááēáá áēáá¯ááᯠáááēááąáŦááēááŧááēá¸/á ááēá¸áááēááŧááēá¸/áá¯ááēááąááŧááēá¸áĄááŊááē áĄááŊáąááŊáąááá¯ááēááá¯ááēá¸á
GitLab CI ááᯠá áááēáááēáážááēááŧááēá¸áááē ááááá áēááģááēááŊááē áááēááŦá¸áááˇáēáĄááá¯ááēḠáážá¯ááēááŊáąá¸ááąáŦáĄááŧáąáŦááēá¸áĄááŦááá¯ááēááĢá turn-key áĄááŧáąááļááŧááˇáē CI ááᯠáážá áēááŧáááēáááēáážááēáááē áá¯áļááąáŦááēááŧáŽá ááᯠáááēáááē á¤ááá ášá áĄááŊááē áĄááģáąáŦáēáááēá¸áážááˇáē ááąá¸ááŊáŦááąááĢáááēá ááá¯áˇáĄááŧááēá GitLab á áŦááŊááēá áŦáááēá¸áááēáĄááŊááēáááá¯áĄááēááąáŦáˇááĢá áááááŧáąáážááēá¸ááá¯áážááēá¸ááá¯áˇ áááŧáąáŦááēááĢáá˛áˇá áááēá¸áááē áááēá¸ááģážáąáŦááēááąáá°á ááŧáąáážááēá¸ááģáŦá¸áĄáąáŦááēááŊááē ááąáĢáēááŦáááē (áááēáá°ááŧáąáŦáᲠááážááēááááąáŦáˇááĢá :)
áá¯áļáˇááŧááēááģááēáááá¯áˇ áááēá¸ááŦááĢáááēá
ááŦáááˇáēááąáŦááēá¸ááĢá¸ááŊááē áááˇáēááŊááē shell runner áá áēáá¯ááŦáážáááģážááē ááąáĢááēá¸á ááēá ááēá¸áááēáážá¯ááģáŦá¸ááŧááˇáē áĄáá¯ááēááģáŦá¸ááᯠáĄááŧáá¯ááēáĄááá¯ááēáá¯ááēááąáŦááēáááē (docker-compose ááá¯áĄáá¯áļá¸ááŧá¯á á ááēá¸áááēáážá¯áĄáąáŦááēááŊááē áááēááąáŦááēáážá¯ááģáŦá¸ááᯠáá¯ááēááąáŦááēááąáááē) ááŊááē GitLab CI ááᯠáááēááá¯áˇ configure áá¯ááēááááēááᯠááŊáąá¸ááŊáąá¸ááĢáááēá
source: www.habr.com
