In May 2019, GitHub announced the release of the Package Registry service. Following this, already in August, the support for CI / CD in Actions was announced .
In the article I will tell you what kind of services are and how this can be used on the example of a small pet project on GitHub.
GitHub Actions is a platform that allows you to manage the software life cycle, the source code of which is hosted on GitHub. In fact, TravisCI, CircleCI and many other free CI / CD platforms received a new competitor in the person of Actions.
GitHub Package Registry is the central repository of artifacts; there are currently five different types of artifacts supported.
Supported Artifact Types in Actions
Support in Actions | Analogue | Language |
---|---|---|
NPM packages | https://www.npmjs.com/ | Javascript |
Docker images | https://hub.docker.com/ | - |
Maven Artifacts | https://mvnrepository.com/ | Java |
Nuget packages | https://www.nuget.org/ | .NET |
Ruby gems | https://rubygems.org/ | Ruby |
This is a convenient opportunity to have all the artifacts in one place, because it is not always advisable to deploy your Nexus or Artifactory server.
GitHub is becoming more and more similar to GitLab, but somewhere it has already surpassed an opponent, for example, GitLab does not yet support NuGet packages and Ruby gems. In fact, if earlier for open source projects you had to connect external integrations to GitHub, now all the eggs are in one basket. Here let everyone decide whether it is good or bad, but at least it is convenient.
Both services are currently in beta mode, you can register for a beta test on these pages .
Migration from other services is very simple, I migrated several of my pet projects from TravisCI and DockerHub to Actions and Package Registry respectively.
I will show you how it looks in one example. The project is the most common, I wrote about it in this article. Nothing complicated, the usual LaTeX-code, with the help of which artifacts are collected (2 PDF files), they are published in GitHub releases. In order not to download a bunch of LaTeX packages, I wrote a Dockerfile so that you can conveniently work from under any OS.
In order to start working with Package Registry instead of DockerHub, you need to take only two simple steps.
We create a token in the GitHub settings (the token must have rights to write and read artifacts).
Token Creation Page
And then we can authenticate with the created token and push artifacts, that's how simple it is:
docker login docker.pkg.github.com --username amet13 docker tag docker-latex:0.0.1 docker.pkg.github.com/amet13/master-thesis/docker-latex:0.0.1 docker push docker.pkg.github.com/amet13/master-thesis/docker-latex:0.0.1
Please note, I specifically indicated my nickname on GitHub in lower case, otherwise you will get an error from Docker:
Error parsing reference: "docker.pkg.github.com/Amet13/master-thesis/docker-latex:0.0.1" is not a valid repository/tag: invalid reference format: repository name must be lowercase
Here's what it looks like in the GitHub web interface:
Package Registry Page for Docker Images
In addition to instructions for downloading the latest image, download statistics are available, the ability to download a separate Docker layer via the web interface, image download history is available.
Actions are a little more complicated, but for those who have ever worked with any other CI / CD system, it will not be difficult to understand. The configuration in Actions is described by declarative YAML, although HCL was used before.
A few basic concepts (I will not intentionally translate the definitions, in my opinion everything is so clear here):
.github/workflows/
This is what the Job list page in Workflow looks like.
Limitations and Prohibitions:
The most current documentation is available at this link .
And here is the logs of one of the Job
Let's go back to the example, here is what my config looks like, we will analyze it in more detail in parts.
Specify a name for Workflow and describe on which trigger it should fire (a list of all triggers is described in the documentation ):
name: master-thesis on: [push]
On which Virtual Environment run Job:
jobs: build: # ubuntu-latest, ubuntu-18.04, or ubuntu-16.04 # windows-latest, windows-2019, or windows-2016 # macOS-latest or macOS-10.14 runs-on: ubuntu-latest
The first step, in name:
indicate the name of Step (optional), and in uses:
which Action we want to use, in this case, clone the repository:
steps: - name: Checkout repo uses: actions/checkout@v1
At the next step, we do not use Action, but only a set of our commands where we log in to the Package Registry, collect the Docker image and push it into the image repository. In the env:
block env:
set environment variables, we take one of them from secrets:
- name: Build docker image and push it to the registry env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} DOCKER_IMAGE_ORIGIN: "docker.pkg.github.com/amet13/master-thesis/docker-latex" run: | # Pull submodules git submodule init git submodule update --remote # Login to GitHub Packages and build Docker image docker login docker.pkg.github.com -u amet13 -p ${GITHUB_TOKEN} docker pull ${DOCKER_IMAGE_ORIGIN}:latest docker build -t ${DOCKER_IMAGE_ORIGIN}:${GITHUB_SHA} . # Generate PDF artifacts docker run --rm -i \ -v ${PWD}:/master-thesis:Z ${DOCKER_IMAGE_ORIGIN}:${GITHUB_SHA} \ bash -c "latexmk -xelatex -synctex=1 -jobname=master-thesis main.tex" docker run --rm -i \ -v ${PWD}:/master-thesis:Z ${DOCKER_IMAGE_ORIGIN}:${GITHUB_SHA} \ bash -c "cd presentation/ && latexmk -xelatex -synctex=1 -jobname=presentation main.tex" # Publish Docker image to GitHub Packages (with latest tag) docker tag ${DOCKER_IMAGE_ORIGIN}:${GITHUB_SHA} ${DOCKER_IMAGE_ORIGIN}:latest docker push ${DOCKER_IMAGE_ORIGIN}:${GITHUB_SHA} docker push ${DOCKER_IMAGE_ORIGIN}:latest
I am sure that in the near future an Action will appear that will automatically tag and push images instead of manually writing Docker commands.
Adding a secret containing a github token
The next step after building the PDFs is to create a release on GitHub and include the collected artifacts in this release. To automatically create a release, we use a third-party Action, in which in the if:
block you can specify the condition for launching the step - only when creating the tag:
- name: Create GitHub release with artifacts uses: softprops/action-gh-release@v1 if: startsWith(github.ref, 'refs/tags/') with: files: | master-thesis.pdf presentation/presentation.pdf name: "Build ${GITHUB_SHA}" env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
Despite the beta status, both services work well, I’m sure that many things will be finished.
At some points it can be inconvenient, there are no global variables, but this can be done with crutches .
I liked the GitHub approach to abandoning HCL in favor of YAML. I also liked the support of many types of hosts, which are very sparing limits (for now), let's see how it goes on. In general, for simple pipelines in public repositories on GitHub, such a bunch will work very well.
The translation of this article is already on medium .