Skip to content

nightly-release

nightly-release #53

Workflow file for this run

name: nightly-release
on:
schedule:
- cron: "30 23 * * *"
workflow_dispatch:
inputs:
force:
description: Force a nightly release even without new commits since the previous nightly.
required: false
default: false
type: boolean
permissions:
contents: write
concurrency:
group: nightly-release
cancel-in-progress: false
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
should_release: ${{ steps.version.outputs.should_release }}
version: ${{ steps.version.outputs.version }}
tag: ${{ steps.version.outputs.tag }}
base_version: ${{ steps.version.outputs.base_version }}
latest_nightly_tag: ${{ steps.version.outputs.latest_nightly_tag }}
commit_range: ${{ steps.version.outputs.commit_range }}
head_sha: ${{ steps.version.outputs.head_sha }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Compute Nightly Version
id: version
shell: bash
run: |
force_flag=""
if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.force }}" == "true" ]]; then
force_flag="--force"
fi
python scripts/nightly_version.py $force_flag --format github > nightly.env
cat nightly.env >> "$GITHUB_OUTPUT"
latest_nightly_tag="$(awk -F= '/^latest_nightly_tag=/{print $2}' nightly.env)"
if [[ -n "$latest_nightly_tag" ]]; then
echo "commit_range=${latest_nightly_tag}..HEAD" >> "$GITHUB_OUTPUT"
else
echo "commit_range=HEAD" >> "$GITHUB_OUTPUT"
fi
- name: Show Decision
shell: bash
run: |
echo "should_release=${{ steps.version.outputs.should_release }}"
echo "version=${{ steps.version.outputs.version }}"
echo "tag=${{ steps.version.outputs.tag }}"
build:
needs: prepare
if: needs.prepare.outputs.should_release == 'true'
name: build-${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, macos-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ needs.prepare.outputs.head_sha }}
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install Meson + Ninja
run: python -m pip install --upgrade pip meson ninja
- name: Setup MSVC
if: matrix.os == 'windows-latest'
uses: ilammy/msvc-dev-cmd@v1
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: "6.10.1"
arch: ${{ matrix.os == 'windows-latest' && 'win64_msvc2022_64' || matrix.os == 'macos-latest' && 'clang_64' || 'linux_gcc_64' }}
modules: qtmultimedia qtimageformats
- name: Write Nightly Version
shell: bash
run: |
printf "%s\n" "${{ needs.prepare.outputs.version }}" > VERSION
- name: Configure (Windows)
if: matrix.os == 'windows-latest'
env:
CC: cl
CXX: cl
run: meson setup builddir --backend ninja --buildtype=release -Dgithub_repo=${{ github.repository }} -Dupdate_channel=dev
- name: Configure (Unix)
if: matrix.os != 'windows-latest'
run: meson setup builddir --backend ninja --buildtype=release -Dgithub_repo=${{ github.repository }} -Dupdate_channel=dev
- name: Build
run: meson compile -C builddir
- name: Upload Build Artifact
uses: actions/upload-artifact@v4
with:
name: pakfu-build-${{ matrix.os }}
path: |
builddir/src/pakfu
builddir/src/pakfu.exe
if-no-files-found: error
validate:
needs: [prepare, build]
if: needs.prepare.outputs.should_release == 'true'
name: validate-${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, macos-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.prepare.outputs.head_sha }}
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: "6.10.1"
arch: ${{ matrix.os == 'windows-latest' && 'win64_msvc2022_64' || matrix.os == 'macos-latest' && 'clang_64' || 'linux_gcc_64' }}
modules: qtmultimedia qtimageformats
- name: Download Build Artifact
uses: actions/download-artifact@v4
with:
name: pakfu-build-${{ matrix.os }}
path: .
- name: Prepare Binary Artifact
shell: bash
run: |
mkdir -p builddir/src
target_binary="builddir/src/pakfu"
candidates=("builddir/src/pakfu" "pakfu")
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
target_binary="builddir/src/pakfu.exe"
candidates=("builddir/src/pakfu.exe" "pakfu.exe")
fi
source_binary=""
for candidate in "${candidates[@]}"; do
if [[ -f "$candidate" ]]; then
source_binary="$candidate"
break
fi
done
if [[ -z "$source_binary" ]]; then
echo "Unable to locate downloaded pakfu binary." >&2
find . -maxdepth 4 -type f | sort
exit 1
fi
if [[ "$source_binary" != "$target_binary" ]]; then
mv "$source_binary" "$target_binary"
fi
if [[ "${{ matrix.os }}" != "windows-latest" ]]; then
chmod +x "$target_binary"
fi
echo "PAKFU_BINARY=$target_binary" >> "$GITHUB_ENV"
- name: Configure macOS Runtime Paths
if: matrix.os == 'macos-latest'
shell: bash
run: |
echo "DYLD_FRAMEWORK_PATH=${QT_ROOT_DIR}/lib" >> "$GITHUB_ENV"
echo "DYLD_LIBRARY_PATH=${QT_ROOT_DIR}/lib" >> "$GITHUB_ENV"
echo "DYLD_FALLBACK_FRAMEWORK_PATH=${QT_ROOT_DIR}/lib" >> "$GITHUB_ENV"
- name: Validate Build
shell: bash
run: |
python scripts/validate_build.py \
--binary "${PAKFU_BINARY}" \
--expected-version "${{ needs.prepare.outputs.version }}"
package:
needs: [prepare, build, validate]
if: needs.prepare.outputs.should_release == 'true'
name: package-${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, macos-latest, ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.prepare.outputs.head_sha }}
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: "6.10.1"
arch: ${{ matrix.os == 'windows-latest' && 'win64_msvc2022_64' || matrix.os == 'macos-latest' && 'clang_64' || 'linux_gcc_64' }}
modules: qtmultimedia qtimageformats
- name: Download Build Artifact
uses: actions/download-artifact@v4
with:
name: pakfu-build-${{ matrix.os }}
path: .
- name: Prepare Binary Artifact
shell: bash
run: |
mkdir -p builddir/src
target_binary="builddir/src/pakfu"
candidates=("builddir/src/pakfu" "pakfu")
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
target_binary="builddir/src/pakfu.exe"
candidates=("builddir/src/pakfu.exe" "pakfu.exe")
fi
source_binary=""
for candidate in "${candidates[@]}"; do
if [[ -f "$candidate" ]]; then
source_binary="$candidate"
break
fi
done
if [[ -z "$source_binary" ]]; then
echo "Unable to locate downloaded pakfu binary." >&2
find . -maxdepth 4 -type f | sort
exit 1
fi
if [[ "$source_binary" != "$target_binary" ]]; then
mv "$source_binary" "$target_binary"
fi
if [[ "${{ matrix.os }}" != "windows-latest" ]]; then
chmod +x "$target_binary"
fi
- name: Write Nightly Version
shell: bash
run: |
printf "%s\n" "${{ needs.prepare.outputs.version }}" > VERSION
- name: Detect Package Architecture (Unix)
if: matrix.os != 'windows-latest'
shell: bash
run: |
arch="$(uname -m)"
case "$arch" in
x86_64|amd64) arch="x64" ;;
aarch64|arm64) arch="arm64" ;;
esac
echo "PAKFU_ARCH=$arch" >> "$GITHUB_ENV"
- name: Detect Package Architecture (Windows)
if: matrix.os == 'windows-latest'
shell: pwsh
run: |
$arch = $env:PROCESSOR_ARCHITECTURE
if ($arch -eq "AMD64") { $arch = "x64" }
elseif ($arch -eq "ARM64") { $arch = "arm64" }
"$([string]::Format('PAKFU_ARCH={0}', $arch))" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
- name: Package (Windows)
if: matrix.os == 'windows-latest'
shell: pwsh
run: |
./scripts/package_windows.ps1 `
-BuildDir builddir `
-OutDir dist `
-Version "${{ needs.prepare.outputs.version }}" `
-Arch "$env:PAKFU_ARCH"
- name: Package (macOS)
if: matrix.os == 'macos-latest'
shell: bash
run: |
bash scripts/package_macos.sh builddir dist "${{ needs.prepare.outputs.version }}" "${PAKFU_ARCH}"
- name: Package (Linux)
if: matrix.os == 'ubuntu-latest'
shell: bash
run: |
bash scripts/package_linux.sh builddir dist "${{ needs.prepare.outputs.version }}" "${PAKFU_ARCH}"
- name: Validate Packaged Assets
shell: bash
run: |
platform="linux"
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
platform="windows"
elif [[ "${{ matrix.os }}" == "macos-latest" ]]; then
platform="macos"
fi
python scripts/validate_release_assets.py \
--dist dist \
--version "${{ needs.prepare.outputs.version }}" \
--platform "$platform" \
--arch "${PAKFU_ARCH}"
- name: Upload Package Artifact
uses: actions/upload-artifact@v4
with:
name: pakfu-dist-${{ matrix.os }}
path: dist/*
if-no-files-found: error
release:
needs: [prepare, package]
if: needs.prepare.outputs.should_release == 'true'
name: github-release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ needs.prepare.outputs.head_sha }}
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Download Package Artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: Write Nightly Version
shell: bash
run: |
printf "%s\n" "${{ needs.prepare.outputs.version }}" > VERSION
- name: Update Changelog Snapshot
shell: bash
run: |
release_date="$(date -u +%F)"
python scripts/update_changelog.py --version "${{ needs.prepare.outputs.version }}" --date "$release_date"
cp CHANGELOG.md "dist/CHANGELOG-${{ needs.prepare.outputs.version }}.md"
- name: Build Nightly Release Notes
shell: bash
run: |
python scripts/nightly_release_notes.py \
--version "v${{ needs.prepare.outputs.version }}" \
--commit-range "${{ needs.prepare.outputs.commit_range }}" \
--include-full-changelog \
--output release_notes.md
- name: Generate Distribution Manifest
shell: bash
run: |
python scripts/release_manifest.py \
--dist dist \
--version "${{ needs.prepare.outputs.version }}" \
--output "dist/pakfu-${{ needs.prepare.outputs.version }}-release-manifest.json"
- name: Validate Release Asset Completeness
shell: bash
run: |
python scripts/validate_release_assets.py --dist dist --version "${{ needs.prepare.outputs.version }}"
- name: Create and Push Tag
shell: bash
run: |
tag="v${{ needs.prepare.outputs.version }}"
git fetch --tags --force
if git rev-parse -q --verify "refs/tags/${tag}" >/dev/null; then
echo "Tag ${tag} already exists."
else
git tag "${tag}" "${{ needs.prepare.outputs.head_sha }}"
git push origin "${tag}"
fi
- name: Publish Nightly Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.prepare.outputs.version }}
name: Nightly v${{ needs.prepare.outputs.version }}
files: dist/**
body_path: release_notes.md
generate_release_notes: false
fail_on_unmatched_files: true
prerelease: false
no-changes:
needs: prepare
if: needs.prepare.outputs.should_release != 'true'
runs-on: ubuntu-latest
steps:
- name: Skip Release
run: |
echo "No commits since previous nightly. Skipping release."