Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 28 additions & 10 deletions .github/workflows/build-exes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ name: Build Windows EXEs
on:
push:
branches:
- main
tags:
- 'v*'
- dev
pull_request:
workflow_dispatch:

Expand Down Expand Up @@ -87,8 +85,8 @@ jobs:
if-no-files-found: error

release:
name: Publish Release
if: startsWith(github.ref, 'refs/tags/v')
name: Publish Rolling Release
if: github.ref == 'refs/heads/dev'
needs: build-windows-x64
runs-on: ubuntu-latest
permissions:
Expand All @@ -99,14 +97,34 @@ jobs:
uses: actions/download-artifact@v4
with:
name: fca-exes-windows-x64
path: dist/windows-x64

- name: Create Release and upload assets
- name: Remove existing rolling assets
shell: bash
run: |
if gh release view rolling --json assets -q '.assets[].name' > /tmp/rolling_assets.txt; then
cat /tmp/rolling_assets.txt | xargs -r -I {} gh release delete-asset rolling "{}" -y
else
echo "Rolling release not found yet; skipping asset cleanup."
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}

- name: Create or update rolling release and upload assets
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
name: Release ${{ github.ref_name }}
tag_name: rolling
name: Rolling Release
target_commitish: ${{ github.sha }}
body: |
Build from ${{ github.sha }}

${{ github.event.head_commit.message }}
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The github.event.head_commit.message may be null or unavailable in certain workflow trigger contexts (such as workflow_dispatch or when pushing multiple commits). This could result in an incomplete or missing commit message in the release body. Consider adding a fallback or checking if head_commit exists before accessing its message property.

Suggested change
${{ github.event.head_commit.message }}
${{ github.event.head_commit && github.event.head_commit.message || 'No head commit message available for this event.' }}

Copilot uses AI. Check for mistakes.
files: dist/windows-x64/*
generate_release_notes: true
allow_updates: true
generate_release_notes: false
overwrite_files: true
make_latest: true
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
135 changes: 135 additions & 0 deletions .github/workflows/manual-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
name: Manual Release

on:
workflow_dispatch:
inputs:
release_tag:
description: "Release tag (e.g., v1.2.3)"
required: true
type: string
release_name:
description: "Release title"
required: true
type: string
release_notes:
description: "Release notes (optional; leave blank to auto-generate)"
required: false
type: string
prerelease:
description: "Mark this release as a prerelease"
required: true
type: boolean
default: false

jobs:
test:
name: Test (unittest + pytest)
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install dependencies
working-directory: python
run: |
python -m pip install --upgrade pip
pip install -r requirements-build.txt
pip install pytest

- name: Run unit tests
working-directory: python
run: python -m unittest discover -s tests -v

- name: Run pytest
working-directory: python
run: pytest tests/ -v

build-windows-x64:
name: Build (windows-x64)
needs: test
runs-on: windows-latest
timeout-minutes: 30

steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install build dependencies
working-directory: python
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements-build.txt

- name: Run parity smoke test
working-directory: python
run: |
python -m unittest tests.test_fca_unittest.TestFCAToolParity.test_tool_encode_decode_matches_standalone -v

- name: Ensure icon file exists
working-directory: python
run: |
if (!(Test-Path small-logo.ico)) {
python build_icon.py --input-file small-logo.png --output-file small-logo.ico
}

- name: Build executables
working-directory: python
run: |
python -m PyInstaller --clean --noconfirm --onefile --icon small-logo.ico --name fca-encode --distpath ../dist/windows-x64 fca_encode.py
python -m PyInstaller --clean --noconfirm --onefile --icon small-logo.ico --name fca-decode --distpath ../dist/windows-x64 fca_decode.py
python -m PyInstaller --clean --noconfirm --onefile --icon small-logo.ico --name fca-tool --distpath ../dist/windows-x64 fca_tool.py

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: fca-exes-windows-x64
path: dist/windows-x64
if-no-files-found: error

release:
name: Publish Release
needs: build-windows-x64
runs-on: ubuntu-latest
permissions:
contents: write

steps:
- name: Download windows-x64 artifacts
uses: actions/download-artifact@v4
with:
name: fca-exes-windows-x64
path: dist/windows-x64

- name: Create release and upload assets
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ inputs.release_tag }}
name: ${{ inputs.release_name }}
target_commitish: ${{ github.sha }}
body: ${{ inputs.release_notes }}
generate_release_notes: ${{ inputs.release_notes == '' }}
files: dist/windows-x64/*
overwrite_files: true
make_latest: true
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The manual release workflow sets make_latest: true unconditionally, which could conflict with the rolling release workflow that also sets make_latest: true. If a manual release is created while a rolling release exists, both would be marked as latest, which may cause confusion. Consider adding logic to coordinate which release should be marked as latest, or document the intended behavior when both release types coexist.

Copilot uses AI. Check for mistakes.
prerelease: ${{ inputs.prerelease }}
fail_on_unmatched_files: true
# Placeholder for custom changelog input:
# append_body: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Loading