mirror of
https://github.com/sebastiandine/Card-Collection-Manager-3.git
synced 2026-08-28 23:01:09 +00:00
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:
@@ -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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user