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.

What kind of services are these?
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
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.
How to try?
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.
Package registry
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
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):
- Workflow - a process that manages the software life cycle (build, test, package, release, deploy) for the repository
- Workflow file - the file in which Workflow is described, it is located in the root of the repository in the directory
.github/workflows/
- Job is every run of Workflow, Job is triggered, at one time a lot of Job can be started
- Step - each Job has a Step, at each Step you can run commands or Actions
- Action - a “plugin” written by someone before, a list of many Actions can be found in the awesome-actions repository
- Virtual environment - the environment on which Job runs (in fact it is a virtual machine on Windows, macOS or Linux)
- Runner is a deployed environment for launching a Job, only one Job can run on Runner at a time
- Event - an event that triggers Workflow, for example, Push, Pull Request, Webhook, Cron Job, etc.
- Artifact - artifacts (binaries, images, logs, etc.)

This is what the Job list page in Workflow looks like.
Limitations and Prohibitions:
- 20 Workflows per repository
- 1000 API requests per hour for all Actions in the repository
- maximum job time - 6 hours
- 20 Jobs can work in parallel in the repository (for all Workflows)
- it is forbidden to use Actions for cryptocurrency mining and serverless computing
The most current documentation is available at this link .

And here is the logs of one of the Job
Example
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 }}
Summary
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 .