feat: enhance CI/CD workflows with Docker support and artifact management

This commit is contained in:
Aaron Kimbrell
2026-05-28 13:24:37 -05:00
parent 4ab09cf1aa
commit bba8d33719
7 changed files with 260 additions and 5 deletions

View File

@@ -1,14 +1,14 @@
name: CI
name: Docker
on:
push:
branches:
- "main"
- main
tags:
- "v*.*.*"
pull_request:
branches:
- "main"
- main
env:
REGISTRY: ghcr.io
@@ -20,6 +20,8 @@ jobs:
permissions:
contents: read
packages: write
attestations: write
id-token: write
steps:
- name: Checkout repository
@@ -27,7 +29,11 @@ jobs:
with:
submodules: recursive
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the Container registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
@@ -39,18 +45,29 @@ jobs:
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# generate Docker tags based on the following events/attributes
tags: |
type=ref,event=pr
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
type=raw,value=canary,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
id: push
uses: docker/build-push-action@v6
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
- name: Generate artifact attestation
if: github.event_name != 'pull_request'
uses: actions/attest-build-provenance@v2
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true

View File

@@ -3,6 +3,8 @@ name: CI
on:
push:
branches: [ main ]
tags:
- "v*.*.*"
pull_request:
branches: [ main ]

93
.github/workflows/canary.yml vendored Normal file
View File

@@ -0,0 +1,93 @@
name: Canary
on:
workflow_run:
workflows: ["CI"]
branches: [main]
types: [completed]
permissions:
contents: write
actions: read
jobs:
canary-release:
name: Publish Canary Release
if: github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.workflow_run.head_sha }}
- name: Get last release tag
id: last_tag
run: |
tag=$(git describe --tags --abbrev=0 --match "v*.*.*" 2>/dev/null || echo "none")
echo "tag=$tag" >> "$GITHUB_OUTPUT"
- name: Generate changelog since last release tag
uses: orhun/git-cliff-action@v4
id: cliff
with:
config: cliff.toml
args: --unreleased --strip header
env:
OUTPUT: CHANGES.md
GITHUB_REPO: ${{ github.repository }}
- name: Prepend header to changelog
run: |
last="${{ steps.last_tag.outputs.tag }}"
sha="${{ github.event.workflow_run.head_sha }}"
short="${sha:0:7}"
if [ "$last" != "none" ]; then
header="Changes since **$last** ([full diff](https://github.com/${{ github.repository }}/compare/${last}...${sha}))\n\n"
else
header="Changes up to \`${short}\`\n\n"
fi
printf "%b" "$header" | cat - CHANGES.md > CHANGES.tmp && mv CHANGES.tmp CHANGES.md
- name: Download artifacts from CI run
uses: dawidd6/action-download-artifact@v6
with:
run_id: ${{ github.event.workflow_run.id }}
path: artifacts/
- name: Package artifacts
run: |
declare -A platform_map=(
["build-windows-2022"]="darkflame-universe-windows"
["build-ubuntu-22.04"]="darkflame-universe-linux"
["build-macos-15-intel"]="darkflame-universe-macos"
)
cd artifacts
for dir in */; do
name="${dir%/}"
out="${platform_map[$name]:-$name}"
zip -r "../${out}.zip" "$dir"
done
cd ..
ls -lh *.zip
- name: Delete existing canary release
run: gh release delete canary --yes --cleanup-tag 2>/dev/null || true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create canary pre-release
uses: ncipollo/release-action@v1
with:
tag: canary
name: "Canary ${{ steps.last_tag.outputs.tag }}+${{ github.event.workflow_run.head_sha }}"
bodyFile: CHANGES.md
artifacts: "*.zip"
artifactContentType: application/zip
token: ${{ secrets.GITHUB_TOKEN }}
prerelease: true
draft: false
allowUpdates: true
removeArtifacts: true
commit: ${{ github.event.workflow_run.head_sha }}

37
.github/workflows/pr-title-check.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: PR Title Check
on:
pull_request:
types: [opened, edited, synchronize, reopened]
permissions:
pull-requests: read
jobs:
check-title:
name: Conventional Commit Title
runs-on: ubuntu-latest
steps:
- name: Check PR title follows Conventional Commits
uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
feat
fix
perf
refactor
docs
chore
test
ci
revert
requireScope: false
subjectPattern: ^.+$
subjectPatternError: |
The PR title "{title}" must have a description after the type/scope prefix.
Example: "feat: add new login flow" or "fix(auth): handle null token"
wip: true
validateSingleCommit: false

69
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,69 @@
name: Release
on:
workflow_run:
workflows: ["CI"]
types: [completed]
permissions:
contents: write
actions: read
jobs:
release:
name: Create Release
# Only run when CI completed successfully on a version tag
if: |
github.event.workflow_run.conclusion == 'success' &&
startsWith(github.event.workflow_run.head_branch, 'v')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.workflow_run.head_sha }}
- name: Generate changelog
uses: orhun/git-cliff-action@v4
id: cliff
with:
config: cliff.toml
args: --latest --strip header
env:
OUTPUT: CHANGES.md
GITHUB_REPO: ${{ github.repository }}
- name: Download artifacts from CI run
uses: dawidd6/action-download-artifact@v6
with:
run_id: ${{ github.event.workflow_run.id }}
path: artifacts/
- name: Package artifacts
run: |
declare -A platform_map=(
["build-windows-2022"]="darkflame-universe-windows"
["build-ubuntu-22.04"]="darkflame-universe-linux"
["build-macos-15-intel"]="darkflame-universe-macos"
)
cd artifacts
for dir in */; do
name="${dir%/}"
out="${platform_map[$name]:-$name}"
zip -r "../${out}.zip" "$dir"
done
cd ..
ls -lh *.zip
- name: Create GitHub Release
uses: ncipollo/release-action@v1
with:
tag: ${{ github.event.workflow_run.head_branch }}
name: ${{ github.event.workflow_run.head_branch }}
bodyFile: CHANGES.md
artifacts: "*.zip"
artifactContentType: application/zip
token: ${{ secrets.GITHUB_TOKEN }}
prerelease: false
draft: false

2
.gitignore vendored
View File

@@ -126,3 +126,5 @@ docker-compose.override.yml
# CMake scripts
!cmake/*
!cmake/toolchains/*
.mcp.json
.claude/

35
cliff.toml Normal file
View File

@@ -0,0 +1,35 @@
[changelog]
header = ""
body = """
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | upper_first }}
{% for commit in commits %}
- {% if commit.scope %}**{{ commit.scope }}**: {% endif %}{{ commit.message }} ([{{ commit.id | truncate(length=7, end="") }}](https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}/commit/{{ commit.id }}))\
{% if commit.github.username %} by [@{{ commit.github.username }}](https://github.com/{{ commit.github.username }}){% endif %}
{% endfor %}
{% endfor %}
"""
footer = ""
trim = true
[git]
conventional_commits = true
filter_unconventional = true
split_commits = false
commit_parsers = [
{ message = "^feat", group = "Features" },
{ message = "^fix", group = "Bug Fixes" },
{ message = "^perf", group = "Performance" },
{ message = "^refactor", group = "Refactoring" },
{ message = "^docs", group = "Documentation" },
{ message = "^chore", group = "Chores" },
{ message = "^test", group = "Testing" },
{ message = "^ci", group = "CI/CD" },
{ message = "^revert", group = "Reverts" },
]
filter_commits = false
tag_pattern = "v[0-9].*"
skip_tags = "canary"
ignore_tags = ""
topo_order = false
sort_commits = "oldest"