major: initial release

* initial development

* pipeline

* pipeline

* pipeline

* pipeline

* pipeline

* pipeline

* pipeline

* pipeline

* pipeline

* pipeline

* pipeline

* pipeline

* pipeline

* pipeline

* ci/cd

* ci/cd

* ci/cd

* ci/cd

* ci/cd

* ci/cd

* ci/cd

* pokemon

* pokemon

* pokemon

* pokemon

* pokemon

* pokemon

* improvements

* improvements

* ci/cd

* ci/cd

* improvements

* improvements

* improvements

* improvements

* improvements

* improvements

* improvements

* improvements

* improvements

---------

Co-authored-by: sdine <sdine@sdine.com>
This commit is contained in:
Sebastian Dine
2026-05-09 11:05:47 +02:00
committed by GitHub
parent 13262fa015
commit 55ace147bc
149 changed files with 12611 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
# AGENTS.md
GitHub Actions workflows for CI, release automation, and policy checks.
## Scope
- This file governs edits in `.github/workflows/*.yml`.
- Keep one top-level triggered workflow per CI intent:
- `feature-ci.yml` for non-`master` push CI
- `master-ci.yml` for merged-PR-to-`master` release CI
- Keep OS/platform splits in reusable workflows invoked via `workflow_call`.
## Current workflow map
- `feature-ci.yml` -> orchestrator for feature branch CI.
- `feature-linux.yml` -> reusable Linux build/test/package workflow.
- `feature-windows.yml` -> reusable Windows build/test/package workflow.
- `master-pr-title-guard.yml` -> validates semantic-prefix policy for PRs targeting `master`.
- `master-ci.yml` -> orchestrator for merged PRs into `master`.
- `master-windows.yml` -> reusable Windows build/test/package workflow for master release flow.
## CI invariants (do not break)
1. Keep workflow intent stable:
- feature workflows produce branch+sha artifacts
- master workflows produce semver-tagged release artifacts
2. Do not duplicate top-level triggers for the same intent (avoid split runs in Actions UI).
3. Preserve artifact naming conventions unless docs are updated in the same change:
- `ccm3-linux-<version>.zip`
- `ccm3-windows-<version>.zip`
- `ccm3-windows-installer-<version>` (feature) and `.exe` (master release asset)
4. Preserve embedded app version wiring via `-DCCM_APP_VERSION=...` in both feature and master build flows.
5. Keep `master` release flow gated to merged PRs only.
6. Keep PR title prefix policy aligned with `scripts/compute_master_semver.sh`.
## Editing rules
- Prefer minimal, surgical edits; avoid large workflow rewrites unless requested.
- Reusable workflows should declare explicit `workflow_call` inputs for required context (e.g., version, merge SHA).
- Keep `permissions` least-privilege:
- reusable build workflows: `contents: read`
- release/tag orchestrator: `contents: write`
- Keep shells consistent with runner setup:
- Linux steps use standard bash-compatible shell.
- Windows MSYS2 jobs keep `shell: msys2 {0}` and run `msys2/setup-msys2` before MSYS2 commands.
## Required follow-ups
- After changing workflow topology, update `docs/ci-cd-guide.md`.
- If artifact names or release behavior change, update `docs/ci-cd-guide.md` and `docs/versioning.md` if needed.
- If semver prefix policy changes, update both `master-pr-title-guard.yml` and docs.
- If adding/removing workflow files, update this file's "Current workflow map".
## Anti-patterns
- Do not add a second top-level feature or master trigger file.
- Do not move release creation into a reusable workflow that lacks `contents: write`.
- Do not introduce MSVC-specific build commands; project CI targets Clang/MinGW toolchains.
- Do not silently change artifact names; downstream release/download steps depend on exact names.
+18
View File
@@ -0,0 +1,18 @@
name: Feature CI
on:
push:
branches-ignore:
- master
permissions:
contents: read
jobs:
linux:
name: Linux build + tests
uses: ./.github/workflows/feature-linux.yml
windows:
name: Windows build + tests
uses: ./.github/workflows/feature-windows.yml
+87
View File
@@ -0,0 +1,87 @@
name: Feature Linux Build, Test, and Package
on:
workflow_call:
permissions:
contents: read
jobs:
build-linux:
name: Linux build + tests
runs-on: ubuntu-latest
env:
CCACHE_DIR: ${{ github.workspace }}/.ccache
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Compute feature version
run: |
VERSION="$(bash scripts/compute_feature_version.sh "${GITHUB_REF_NAME}" "${GITHUB_SHA}")"
echo "VERSION=${VERSION}" >> "$GITHUB_ENV"
- name: Install build tools
run: >
sudo apt-get update &&
sudo apt-get install -y
ninja-build
ccache
pkg-config
libgtk-3-dev
libwxgtk3.2-dev
- name: Restore Linux compiler cache
uses: actions/cache@v4
with:
path: ${{ env.CCACHE_DIR }}
key: ccache-linux-${{ github.ref_name }}-v1
restore-keys: |
ccache-linux-${{ github.ref_name }}-
ccache-linux-
- name: Configure
run: >
cmake -S . -B build -G Ninja
-DCCM_BUILD_TESTS=ON
-DCCM_USE_SYSTEM_WX=ON
-DCCM_APP_VERSION="${VERSION}"
-DCMAKE_C_COMPILER_LAUNCHER=ccache
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- name: Build
run: cmake --build build --parallel 3
- name: Run unit tests
run: ctest --test-dir build --output-on-failure
- name: Remove test executable from bundle
run: rm -f build/bin/ccm_core_tests
- name: Verify runtime dependencies are resolved
run: |
for f in build/bin/*; do
[ -f "$f" ] || continue
if file "$f" | grep -q "ELF"; then
echo "Checking $f"
ldd "$f"
if ldd "$f" | grep -q "not found"; then
echo "Missing runtime dependency detected in $f"
exit 1
fi
fi
done
- name: Stage Linux artifact folder
run: |
rm -rf dist/ccm3-linux
mkdir -p dist/ccm3-linux
cp -a build/bin/. dist/ccm3-linux/
- name: Upload Linux artifact
uses: actions/upload-artifact@v4
with:
name: ccm3-linux-${{ env.VERSION }}.zip
path: dist/ccm3-linux
if-no-files-found: error
+122
View File
@@ -0,0 +1,122 @@
name: Feature Windows Build, Test, and Package
on:
workflow_call:
permissions:
contents: read
jobs:
build-windows:
name: Windows build + tests
runs-on: windows-latest
env:
CCACHE_DIR_WIN: ${{ github.workspace }}\.ccache
defaults:
run:
shell: msys2 {0}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup MSYS2 (MinGW-w64 UCRT64)
uses: msys2/setup-msys2@v2
with:
msystem: UCRT64
update: true
cache: true
install: >-
mingw-w64-ucrt-x86_64-gcc
mingw-w64-ucrt-x86_64-cmake
mingw-w64-ucrt-x86_64-ninja
mingw-w64-ucrt-x86_64-make
mingw-w64-ucrt-x86_64-ccache
mingw-w64-ucrt-x86_64-wxwidgets3.2-msw
mingw-w64-ucrt-x86_64-nsis
- name: Compute feature version
run: |
VERSION="$(bash scripts/compute_feature_version.sh "${GITHUB_REF_NAME}" "${GITHUB_SHA}")"
echo "VERSION=${VERSION}" >> "$GITHUB_ENV"
- name: Restore Windows compiler cache
uses: actions/cache@v4
with:
path: ${{ env.CCACHE_DIR_WIN }}
key: ccache-windows-${{ github.ref_name }}-v2
restore-keys: |
ccache-windows-${{ github.ref_name }}-
ccache-windows-
- name: Configure MSYS2 ccache directory
run: |
CCACHE_DIR_POSIX="$(cygpath -u "$CCACHE_DIR_WIN")"
echo "CCACHE_DIR=${CCACHE_DIR_POSIX}" >> "$GITHUB_ENV"
mkdir -p "$CCACHE_DIR_POSIX"
- name: Configure
run: >
cmake -S . -B build -G Ninja
-DCMAKE_BUILD_TYPE=Release
-DCCM_BUILD_TESTS=ON
-DCCM_USE_SYSTEM_WX=ON
-DCCM_APP_VERSION="${VERSION}"
-DCMAKE_C_COMPILER_LAUNCHER=ccache
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- name: Build
run: cmake --build build --parallel 4
- name: Run unit tests
run: ctest --test-dir build --output-on-failure
- name: Collect runtime DLL dependencies
run: |
rm -f deps.txt
for f in build/bin/*.exe build/bin/*.dll; do
[ -e "$f" ] || continue
ldd "$f" | awk '/\/ucrt64\/bin\// { print $3 }' >> deps.txt
done
sort -u deps.txt | while read -r dep; do
[ -f "$dep" ] && cp -n "$dep" build/bin/
done
- name: Verify runtime dependencies are resolved
run: |
for f in build/bin/*.exe build/bin/*.dll; do
[ -e "$f" ] || continue
echo "Checking $f"
ldd "$f"
if ldd "$f" | grep -q "not found"; then
echo "Missing runtime dependency detected in $f"
exit 1
fi
done
- name: Remove test executable from bundle
run: rm -f build/bin/ccm_core_tests.exe build/bin/ccm_core_tests
- name: Build Windows installer
run: makensis -DAPP_VERSION="${VERSION}" scripts/installer.nsi
- name: Stage Windows artifact folder
run: |
rm -rf dist/ccm3-windows
mkdir -p dist/ccm3-windows
cp -a build/bin/. dist/ccm3-windows/
- name: Upload Windows artifact
uses: actions/upload-artifact@v4
with:
name: ccm3-windows-${{ env.VERSION }}.zip
path: dist/ccm3-windows
if-no-files-found: error
- name: Upload Windows installer artifact
uses: actions/upload-artifact@v4
with:
name: ccm3-windows-installer-${{ env.VERSION }}
path: ccm3-windows-installer.exe
if-no-files-found: error
+71
View File
@@ -0,0 +1,71 @@
name: Master CI
on:
pull_request:
branches:
- master
types:
- closed
permissions:
contents: write
jobs:
compute-version:
name: Determine semantic version
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
release_tag: ${{ steps.version.outputs.release_tag }}
steps:
- name: Checkout tags
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Resolve semantic version
id: version
run: bash scripts/compute_master_semver.sh "${{ github.event.pull_request.title }}"
build-windows:
name: Windows build + tests
needs: compute-version
uses: ./.github/workflows/master-windows.yml
with:
version: ${{ needs.compute-version.outputs.version }}
merge_commit_sha: ${{ github.event.pull_request.merge_commit_sha }}
release-master:
name: Tag and release on master
needs:
- compute-version
- build-windows
runs-on: ubuntu-latest
steps:
- name: Download Windows artifact
uses: actions/download-artifact@v4
with:
name: ccm3-windows-${{ needs.compute-version.outputs.version }}.zip
path: release/windows
- name: Download Windows installer artifact
uses: actions/download-artifact@v4
with:
name: ccm3-windows-installer-${{ needs.compute-version.outputs.version }}
path: release/installer
- name: Package release assets with semantic version
run: |
mkdir -p release-assets
VERSION="${{ needs.compute-version.outputs.version }}"
zip -r "release-assets/ccm3-windows-${VERSION}.zip" release/windows
cp release/installer/ccm3-windows-installer.exe "release-assets/ccm3-windows-installer-${VERSION}.exe"
- name: Create tag and GitHub release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.compute-version.outputs.release_tag }}
target_commitish: ${{ github.event.pull_request.merge_commit_sha }}
generate_release_notes: true
files: release-assets/*
@@ -0,0 +1,33 @@
name: Master PR Title Guard
on:
pull_request:
branches:
- master
types:
- opened
- edited
- synchronize
- reopened
- ready_for_review
permissions:
contents: read
jobs:
validate-title:
name: Require semver prefix in PR title
runs-on: ubuntu-latest
steps:
- name: Validate pull request title prefix
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
title_lower="$(echo "${PR_TITLE}" | tr '[:upper:]' '[:lower:]')"
if [[ "${title_lower}" == major* || "${title_lower}" == minor* || "${title_lower}" == fix* || "${title_lower}" == patch* || "${title_lower}" == path* ]]; then
echo "PR title is valid: ${PR_TITLE}"
exit 0
fi
echo "Invalid PR title: '${PR_TITLE}'"
echo "Title must start with one of: major, minor, fix, patch, or path."
exit 1
+128
View File
@@ -0,0 +1,128 @@
name: Master Windows Build, Test, and Package
on:
workflow_call:
inputs:
version:
required: true
type: string
merge_commit_sha:
required: true
type: string
permissions:
contents: read
jobs:
build-windows:
name: Windows build + tests
runs-on: windows-latest
env:
CCACHE_DIR_WIN: ${{ github.workspace }}\.ccache
VERSION: ${{ inputs.version }}
defaults:
run:
shell: msys2 {0}
steps:
- name: Checkout merge commit
uses: actions/checkout@v4
with:
ref: ${{ inputs.merge_commit_sha }}
- name: Setup MSYS2 (MinGW-w64 UCRT64)
uses: msys2/setup-msys2@v2
with:
msystem: UCRT64
update: true
cache: true
install: >-
mingw-w64-ucrt-x86_64-gcc
mingw-w64-ucrt-x86_64-cmake
mingw-w64-ucrt-x86_64-ninja
mingw-w64-ucrt-x86_64-make
mingw-w64-ucrt-x86_64-ccache
mingw-w64-ucrt-x86_64-wxwidgets3.2-msw
mingw-w64-ucrt-x86_64-nsis
- name: Restore Windows compiler cache
uses: actions/cache@v4
with:
path: ${{ env.CCACHE_DIR_WIN }}
key: ccache-windows-master-v2
restore-keys: |
ccache-windows-master-
ccache-windows-
- name: Configure MSYS2 ccache directory
run: |
CCACHE_DIR_POSIX="$(cygpath -u "$CCACHE_DIR_WIN")"
echo "CCACHE_DIR=${CCACHE_DIR_POSIX}" >> "$GITHUB_ENV"
mkdir -p "$CCACHE_DIR_POSIX"
- name: Configure
run: >
cmake -S . -B build -G Ninja
-DCMAKE_BUILD_TYPE=Release
-DCCM_BUILD_TESTS=ON
-DCCM_USE_SYSTEM_WX=ON
-DCCM_APP_VERSION="${VERSION}"
-DCMAKE_C_COMPILER_LAUNCHER=ccache
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- name: Build
run: cmake --build build --parallel 4
- name: Run unit tests
run: ctest --test-dir build --output-on-failure
- name: Collect runtime DLL dependencies
run: |
rm -f deps.txt
for f in build/bin/*.exe build/bin/*.dll; do
[ -e "$f" ] || continue
ldd "$f" | awk '/\/ucrt64\/bin\// { print $3 }' >> deps.txt
done
sort -u deps.txt | while read -r dep; do
[ -f "$dep" ] && cp -n "$dep" build/bin/
done
- name: Verify runtime dependencies are resolved
run: |
for f in build/bin/*.exe build/bin/*.dll; do
[ -e "$f" ] || continue
echo "Checking $f"
ldd "$f"
if ldd "$f" | grep -q "not found"; then
echo "Missing runtime dependency detected in $f"
exit 1
fi
done
- name: Remove test executable from bundle
run: rm -f build/bin/ccm_core_tests.exe build/bin/ccm_core_tests
- name: Build Windows installer
run: makensis -DAPP_VERSION="${VERSION}" scripts/installer.nsi
- name: Stage Windows artifact folder
run: |
rm -rf dist/ccm3-windows
mkdir -p dist/ccm3-windows
cp -a build/bin/. dist/ccm3-windows/
- name: Upload Windows artifact
uses: actions/upload-artifact@v4
with:
name: ccm3-windows-${{ env.VERSION }}.zip
path: dist/ccm3-windows
if-no-files-found: error
- name: Upload Windows installer artifact
uses: actions/upload-artifact@v4
with:
name: ccm3-windows-installer-${{ env.VERSION }}
path: ccm3-windows-installer.exe
if-no-files-found: error