Setting up the CI environment
Now we will setup the CI for my intro page.
Obstacle
A push on any branch should trigger a build in Github Actions and test the latest push for any errors. We must make sure that new pushes against the branch will cancel the old one.
For easy deployment, the frontend image will be available at docker.hub.com. Any docker registry can be used here! To enable a comfortable deployment, I will setup an automated push to the docker registry, after the master branch or any tags has been pushed to github.
With jwilder/nginx-proxy is using environment variables to configure each webservice you want to reverse-proxy on your server. To accomplish this with jwilder I had to inject the configurations while building the image.
Since traefik is using labels this is not necessary and saves up some time setting up the CI pipeline and dockerfile.
I ended up using two workflows in my project, one to build the app and one to build and push my docker image.
The docker build and push action is pretty much documented here and you can apply this for your needs.
Mine looks like this:
name: ci
on:
schedule:
- cron: '0 10 * * *' # everyday at 10am
push:
branches:
- 'master'
- 'release/*'
tags:
- 'v*.*.*'
pull_request:
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Use Node.js 14.x
uses: actions/setup-node@v1
with:
node-version: 14.x
-
name: Prepare
id: prep
run: |
DOCKER_IMAGE=radikrahl/andreaskrahl.de
VERSION=noop
if [ "${{ github.event_name }}" = "schedule" ]; then
VERSION=nightly
echo -e "Version is schedule \e[44m${VERSION}"
elif [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
echo -e "Version is refs/tags/ \e[44m${VERSION}"
elif [[ $GITHUB_REF == refs/heads/* ]]; then
VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g')
if [ "${{ github.event.repository.default_branch }}" = "$VERSION" ]; then
VERSION=latest
echo -e "Version is /refs/heads/default/ \e[44m${VERSION}"
fi
echo -e "Version is /refs/head \e[44m${VERSION}"
elif [[ $GITHUB_REF == refs/pull/* ]]; then
VERSION=pr-${{ github.event.number }}
echo -e "Version is /refs/pull/ \e[44m${VERSION}"
fi
DOCKER_TAGS="${DOCKER_IMAGE}:${VERSION}"
if [[ $VERSION =~ ^v[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
MINOR=${VERSION%.*}
MAJOR=${MINOR%.*}
DOCKER_TAGS="$DOCKER_TAGS,${DOCKER_IMAGE}:${MINOR},${DOCKER_IMAGE}:${MAJOR},${DOCKER_IMAGE}:latest"
elif [ "${{ github.event_name }}" = "push" ]; then
DOCKER_TAGS="$DOCKER_TAGS,${DOCKER_IMAGE}:sha-${GITHUB_SHA::8}"
fi
echo -e "Docker tag is \e[44m${DOCKER_TAGS}"
echo -e "Version is \e[44m${VERSION}"
echo ::set-output name=version::${VERSION}
echo ::set-output name=tags::${DOCKER_TAGS}
echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
-
name: bump node version
run: |
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
-
name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
-
name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64,linux/386
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.prep.outputs.tags }}
labels: |
org.opencontainers.image.title=${{ github.event.repository.name }}
org.opencontainers.image.description=${{ github.event.repository.description }}
org.opencontainers.image.url=${{ github.event.repository.html_url }}
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
org.opencontainers.image.version=${{ steps.prep.outputs.version }}
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.licenses=${{ github.event.repository.license.spdx_id }}
The node build is standard too.
# name: Publish Docker image
# on:
# push:
# branches: [ develop ]
# pull_request:
# branches: [ develop ]
name: Node.js CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 12.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm run build --if-present
- run: npm test
- run: npm run lint
env:
CI: true
I used to use travis-ci in my old setup, which took some time to setup, but I was quite satisfied with it since it got the work done!
Midway through Github Actions were released. I always wanted to transition from travis-ci to github actions but could not take the time to do so.
I like both systems since they well documented and easy to integrate. Currently I would say I still like to work with travis, since it is more mature than github actions and "googling" makes it easier.
If you setup your CI Environment be prepared to have a commit history that will look something like this.
That is it my friends. Thanks for reading.