Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5831167
Enhance Doxygen Docker images with non-root user, health checks, and …
Mar 18, 2025
f6b5ca2
Update README.md with enhanced usage instructions, container registri…
Mar 19, 2025
c0559ef
Update Trivy vulnerability scanner action to version 0.30.0
Mar 19, 2025
17f6475
Update Docker publish workflow to use secrets for Quay credentials
Mar 19, 2025
289078c
Add timestamp generation for image creation in Docker publish workflow
Mar 19, 2025
8c93b13
Update Dockerfiles to use latest Alpine and Debian images, enhance di…
Mar 20, 2025
86ff53f
Refactor Dockerfiles to improve readability by organizing package ins…
Mar 20, 2025
4a5e8b3
Enhance Docker publish workflow by adding a hash generation step for …
Mar 20, 2025
78225cb
Consolidate Dockerfiles into a single Dockerfile with multi-architect…
Mar 20, 2025
2bc787f
Refactor Docker publish workflow to streamline build arguments for mu…
Mar 20, 2025
be262c8
Re-declare DISTRO ARG in Dockerfile to ensure availability after FROM…
Mar 20, 2025
16ead7d
Improve user creation logic in Dockerfile to support multiple distrib…
Mar 20, 2025
b12b62f
Update Docker publish workflow to use a single Dockerfile for all dis…
Mar 20, 2025
c365476
Fix entry point command in Dockerfile to reference the correct Doxyge…
Mar 20, 2025
78accbb
Refactor Dockerfile and add entrypoint script to improve user permiss…
Mar 20, 2025
d486b57
Enhance Doxygen version extraction and entrypoint script for improved…
Mar 20, 2025
7304342
Update README.md for improved clarity and structure, including enhanc…
Mar 20, 2025
e34dbba
Update Doxygen logo in README.md to use the SVG version for better qu…
Mar 20, 2025
f790fe7
Remove Doxygen logo from README.md for a cleaner presentation, and no…
Mar 20, 2025
d852d60
Add disclaimer and support section to README.md for clarity on commun…
Mar 20, 2025
cb9067b
Remove version specification from Docker Compose example for flexibility
Mar 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
304 changes: 155 additions & 149 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,190 +4,196 @@ on:
schedule:
- cron: '31 16 * * 1'
workflow_dispatch:
push:
branches: [main]
paths:
- 'Dockerfile'
- '.github/workflows/docker-publish.yml'
pull_request:
branches: [main]
paths:
- 'Dockerfile'
- '.github/workflows/docker-publish.yml'

jobs:
Alpine:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
distro: [alpine, debian]
include:
- distro: alpine
is_latest: true
distro_version: 'latest'
- distro: debian
is_latest: false
debian_version: 'stable-slim'
permissions:
contents: write
contents: read
packages: write
security-events: write

id-token: write # For OIDC auth

steps:
-
name: Docker Setup QEMU
uses: docker/setup-qemu-action@v3
id: qemu
with:
platforms: amd64,arm64,arm
-
name: Docker Setup Buildx
id: buildx
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Log into ghcr.io registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Login to Quay.io
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_ROBOT_TOKEN }}
-
name: Build and test docker image
uses: docker/build-push-action@v6
with:
# context: .
file: ./Dockerfile.alpine
load: true
tags: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:alpine-test
cache-from: type=gha
cache-to: type=gha,mode=max
-
name: Test
run: |
docker run --rm docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:alpine-test doxygen --help
-
name: Retrieve doxygen version
run: |
echo "doxygen_version=$(docker run --rm docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:alpine-test doxygen -v)" >> $GITHUB_OUTPUT
id: version
# ${{ steps.version.outputs.doxygen_version }}
-
name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: image
image-ref: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:alpine-test
format: 'sarif'
output: 'trivy-results-alpine.sarif'
severity: 'MEDIUM,CRITICAL,HIGH'
hide-progress: false
-
name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results-alpine.sarif'
-
name: Build and push Docker image
uses: docker/build-push-action@v6
with:
# context: .
file: ./Dockerfile.alpine
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
tags: |
ghcr.io/kingpin/${{ github.event.repository.name }}:latest
ghcr.io/kingpin/${{ github.event.repository.name }}:alpine
ghcr.io/kingpin/${{ github.event.repository.name }}:alpine-${{ steps.version.outputs.doxygen_version }}
docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:latest
docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:alpine
docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:alpine-${{ steps.version.outputs.doxygen_version }}
quay.io/kingpinx1/${{ github.event.repository.name }}:latest
quay.io/kingpinx1/${{ github.event.repository.name }}:alpine
quay.io/kingpinx1/${{ github.event.repository.name }}:alpine-${{ steps.version.outputs.doxygen_version }}
Debian:

runs-on: ubuntu-latest
permissions:
contents: write
packages: write
security-events: write

steps:
-
name: Docker Setup QEMU

- name: Set up QEMU
uses: docker/setup-qemu-action@v3
id: qemu
with:
platforms: amd64,arm64,arm
-
name: Docker Setup Buildx
id: buildx
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
uses: docker/login-action@v3
platforms: linux/amd64,linux/arm64,linux/arm/v7

# Login to Docker Hub
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Log into ghcr.io registry

# Login to GitHub Container Registry
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Login to Quay.io

# Login to Quay.io
- name: Login to Quay.io
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_ROBOT_TOKEN }}
-
name: Build and test docker image

# Generate Dockerfile hash
- name: Generate Dockerfile hash
id: hash
run: |
echo "hash=$(sha256sum Dockerfile | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT

# Build test image
- name: Build test image
uses: docker/build-push-action@v6
with:
# context: .
file: ./Dockerfile.debian
context: .
file: ./Dockerfile
build-args: |
DISTRO=${{ matrix.distro }}
${{ matrix.distro == 'alpine' && format('DISTRO_VERSION={0}', matrix.distro_version) || format('DEBIAN_VERSION={0}', matrix.debian_version) }}
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conditional build-arg logic is fragile and will cause issues for Debian builds. When DISTRO=debian, this sets DEBIAN_VERSION=stable-slim but the Dockerfile's FROM statement uses ${DISTRO}:${DISTRO_VERSION}, which would result in debian:latest (the default DISTRO_VERSION value). This needs to properly set both DISTRO and the appropriate version variable.

Copilot uses AI. Check for mistakes.
load: true
tags: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:debian-test
cache-from: type=gha
cache-to: type=gha,mode=max
-
name: Test
run: |
docker run --rm docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:debian-test doxygen --help
-
name: Retrieve doxygen version
tags: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:${{ matrix.distro }}-test
cache-from: |
type=gha,scope=${{ matrix.distro }}-${{ steps.hash.outputs.hash }}
type=registry,ref=ghcr.io/kingpin/${{ github.event.repository.name }}:${{ matrix.distro }}-cache
cache-to: |
type=gha,scope=${{ matrix.distro }},mode=max
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cache scope references a hash that is computed but then not used consistently. Line 94 uses scope=${{ matrix.distro }}-${{ steps.hash.outputs.hash }} but line 97 uses scope=${{ matrix.distro }} without the hash. This mismatch means the cache-from won't find the cache created by cache-to, resulting in ineffective caching.

Suggested change
type=gha,scope=${{ matrix.distro }},mode=max
type=gha,scope=${{ matrix.distro }}-${{ steps.hash.outputs.hash }},mode=max

Copilot uses AI. Check for mistakes.
${{ github.ref == 'refs/heads/main' && format('type=registry,ref=ghcr.io/kingpin/{0}:{1}-cache,mode=max', github.event.repository.name, matrix.distro) || '' }}

# Test image
- name: Test image
run: |
echo "doxygen_version=$(docker run --rm docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:debian-test doxygen -v)" >> $GITHUB_OUTPUT
docker run --rm docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:${{ matrix.distro }}-test doxygen --help

# Get Doxygen version
- name: Extract Doxygen version
id: version
# ${{ steps.version.outputs.doxygen_version }}
-
name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
run: |
# Run with environment variable to silence entrypoint output
echo "doxygen_version=$(docker run --rm docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:${{ matrix.distro }}-test doxygen -v | tail -n1 | tr -d '\n')" >> $GITHUB_OUTPUT

# Verify that we got a clean version
if ! [[ $(cat $GITHUB_OUTPUT | grep doxygen_version | cut -d= -f2) =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: Invalid Doxygen version extracted. Check entrypoint script output."
cat $GITHUB_OUTPUT
exit 1
fi

# Vulnerability scan
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.30.0
with:
scan-type: image
image-ref: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:debian-test
image-ref: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:${{ matrix.distro }}-test
format: 'sarif'
output: 'trivy-results-debian.sarif'
output: 'trivy-results-${{ matrix.distro }}.sarif'
severity: 'MEDIUM,CRITICAL,HIGH'
hide-progress: false
-
name: Upload Trivy scan results to GitHub Security tab

# Upload scan results
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results-debian.sarif'
-
name: Build and push Docker image
sarif_file: 'trivy-results-${{ matrix.distro }}.sarif'

# Generate tag lists based on context
- name: Prepare tags
id: prep
run: |
# Generate current timestamp in ISO 8601 format
echo "timestamp=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT

# For PR builds, only create GHCR tags with PR number
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
PR_NUMBER=$(echo $GITHUB_REF | awk -F / '{print $3}')
TAGS="ghcr.io/kingpin/${{ github.event.repository.name }}:${{ matrix.distro }}-pr-${PR_NUMBER}
ghcr.io/kingpin/${{ github.event.repository.name }}:${{ matrix.distro }}-${{ steps.version.outputs.doxygen_version }}-pr-${PR_NUMBER}"

if [ "${{ matrix.is_latest }}" = "true" ]; then
TAGS="$TAGS
ghcr.io/kingpin/${{ github.event.repository.name }}:pr-${PR_NUMBER}"
fi
else
# For main branch, create all registry tags
TAGS="ghcr.io/kingpin/${{ github.event.repository.name }}:${{ matrix.distro }}
docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:${{ matrix.distro }}
quay.io/kingpinx1/${{ github.event.repository.name }}:${{ matrix.distro }}
ghcr.io/kingpin/${{ github.event.repository.name }}:${{ matrix.distro }}-${{ steps.version.outputs.doxygen_version }}
docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:${{ matrix.distro }}-${{ steps.version.outputs.doxygen_version }}
quay.io/kingpinx1/${{ github.event.repository.name }}:${{ matrix.distro }}-${{ steps.version.outputs.doxygen_version }}"

# Add latest tags if this is the latest version
if [ "${{ matrix.is_latest }}" = "true" ]; then
TAGS="$TAGS
ghcr.io/kingpin/${{ github.event.repository.name }}:latest
docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:latest
quay.io/kingpinx1/${{ github.event.repository.name }}:latest"
fi
fi

echo "tags<<EOF" >> $GITHUB_OUTPUT
echo "$TAGS" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

# Build and push the images
- name: Build and push
uses: docker/build-push-action@v6
with:
# context: .
file: ./Dockerfile.debian
context: .
file: ./Dockerfile
build-args: |
DISTRO=${{ matrix.distro }}
${{ matrix.distro == 'alpine' && format('DISTRO_VERSION={0}', matrix.distro_version) || format('DEBIAN_VERSION={0}', matrix.debian_version) }}
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
tags: |
ghcr.io/kingpin/${{ github.event.repository.name }}:debian
docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:debian
quay.io/kingpinx1/${{ github.event.repository.name }}:debian
ghcr.io/kingpin/${{ github.event.repository.name }}:debian-${{ steps.version.outputs.doxygen_version }}
docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:debian-${{ steps.version.outputs.doxygen_version }}
quay.io/kingpinx1/${{ github.event.repository.name }}:debian-${{ steps.version.outputs.doxygen_version }}
push: ${{ github.ref == 'refs/heads/main' || github.event_name == 'pull_request' }}
tags: ${{ steps.prep.outputs.tags }}
cache-from: |
type=gha,scope=${{ matrix.distro }}
docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}:${{ matrix.distro }}-test
type=registry,ref=ghcr.io/kingpin/${{ github.event.repository.name }}:${{ matrix.distro }}-cache
cache-to: |
type=gha,scope=${{ matrix.distro }},mode=max
${{ github.ref == 'refs/heads/main' && format('type=registry,ref=ghcr.io/kingpin/{0}:{1}-cache,mode=max', github.event.repository.name, matrix.distro) || '' }}
labels: |
org.opencontainers.image.title=${{ github.event.repository.name }}
org.opencontainers.image.description=Doxygen container based on ${{ matrix.distro }}
org.opencontainers.image.version=${{ steps.version.outputs.doxygen_version }}
org.opencontainers.image.created=${{ steps.prep.outputs.timestamp }}
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
Loading