Skip to content

Add a Docker build workflow that publishes to GHCR #1

Add a Docker build workflow that publishes to GHCR

Add a Docker build workflow that publishes to GHCR #1

Workflow file for this run

# Build the container image and push it to GHCR.
#
# Build only. Deployment is a separate, manually triggered workflow, so a push
# never changes what is running on a server.
#
# Upstream's pipeline.yml does the same job but triggers on `dev` and `preprod`,
# branches this fork does not have, so it has never run here. Rather than edit a
# tracked upstream file and inherit a conflict on every rebase, this workflow
# sits alongside it and triggers on the branches this fork actually uses.
#
# Images land at ghcr.io/grnet/eudi-srv-web-issuing-eudiw-py, tagged by branch,
# by commit SHA, and as `latest` on the default branch. The SHA tag is the one
# worth deploying: it names exactly one build.
name: Docker build
on:
push:
branches:
- local-deploy-snf-74864-1.2
- 'feat/**'
paths-ignore:
- '**.md'
- '.gitignore'
pull_request:
paths-ignore:
- '**.md'
- '.gitignore'
workflow_dispatch:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
name: Build and push
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.10.0
# Pull requests from forks cannot read secrets, and pushing an image from
# unreviewed code is not something to do by default. Those builds run to
# prove the Dockerfile still works, and stop short of publishing.
- name: Log in to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3.4.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5.7.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha,format=long
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push
uses: docker/build-push-action@v6.15.0
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: false
# The image is only useful if it starts. The issuer needs TLS material,
# its document-signing material, and a rendered config, so the smoke test
# supplies exactly what compose does: a throwaway certificate, the output
# of pki/bootstrap.sh, and the config template the entrypoint renders.
- name: Smoke test the image
if: github.event_name != 'pull_request'
run: |
set -euo pipefail
IMAGE=$(printf '%s' "${{ steps.meta.outputs.tags }}" | head -1)
echo "Testing $IMAGE"
./pki/bootstrap.sh
mkdir -p /tmp/tls
openssl req -x509 -newkey rsa:2048 -sha256 -days 1 -nodes \
-keyout /tmp/tls/issuer.key -out /tmp/tls/issuer.crt \
-subj "/CN=localhost" -addext "subjectAltName=DNS:localhost" 2>/dev/null
cp /tmp/tls/issuer.crt /tmp/tls/ca-bundle.pem
chmod 644 /tmp/tls/*
docker run -d --name smoke \
-e CONFIG_TEMPLATE=/tmp/config.yaml.template \
-e ISSUER_CONFIG_PATH=/config.yaml \
-e ISSUER_PUBLIC_URL=https://localhost:5600 \
-e OIDC_PUBLIC_URL=https://localhost:5601 \
-e OIDC_INTERNAL_URL=https://localhost:5601 \
-e FRONTEND_PUBLIC_URL=https://localhost:5602 \
-e STATUSLIST_PUBLIC_URL=https://localhost:5603 \
-e ISSUER_HOST=localhost \
-v /tmp/tls:/etc/eudiw/tls:ro \
-v "$PWD/pki/out/eudiw:/etc/eudiw/pid-issuer-dev:ro" \
-v "$PWD/docker/config.yaml.template:/tmp/config.yaml.template:ro" \
--entrypoint /usr/local/bin/entrypoint.sh \
"$IMAGE" \
flask --app app:create_app run --host=0.0.0.0 --port=5600 \
--cert=/etc/eudiw/tls/issuer.crt --key=/etc/eudiw/tls/issuer.key
for i in $(seq 1 40); do
if docker exec smoke python3 -c "
import urllib.request, ssl
ctx = ssl._create_unverified_context()
urllib.request.urlopen('https://localhost:5600/.well-known/openid-credential-issuer', context=ctx, timeout=5)
" 2>/dev/null; then
echo "Service answered after ${i}s"
docker rm -f smoke >/dev/null
exit 0
fi
sleep 1
done
echo "::error::the service did not answer within 40s"
docker logs smoke
docker rm -f smoke >/dev/null
exit 1