From f458f55b01534d0932e694d5687a399fe966681f Mon Sep 17 00:00:00 2001 From: Felipe Keller Braz Date: Tue, 7 Apr 2026 17:36:22 -0300 Subject: [PATCH 1/6] feat(release): rework pipeline to build bundles and publish optionally - simplify workflow inputs to release_version + additional_notes - add create_release and is_prerelease flags defaulting to false - orchestrate Linux/macOS Zero Hour builds in release workflow - download generated artifacts and normalize release bundle assets - attach linux zip and macos app.tar.zip on release creation - generate changelog from local-repo PR associations only - add new-contributor section with username and PR URL format - keep fixed release header and install instructions block - upload preview artifacts when create_release is disabled or dry-run - update release pipeline documentation and dev diary --- .github/workflows/release.yml | 398 +++++++++++------------ docs/DEV_BLOG/2026-04-DIARY.md | 33 ++ docs/WORKDIR/support/RELEASE_PIPELINE.md | 265 +++------------ 3 files changed, 272 insertions(+), 424 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 57c53d9c70b..f48de26573d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,33 +4,25 @@ on: workflow_dispatch: inputs: release_version: - description: 'Release version tag (e.g., GeneralsX-Beta-3)' + description: "Release version tag (e.g., GeneralsX-Beta-3)" required: true type: string - build_notes: - description: 'Build notes section (optional markdown)' + additional_notes: + description: "Additional notes (optional markdown)" required: false type: string - known_issues: - description: 'Known issues section (optional markdown)' - required: false - type: string - custom_text: - description: 'Additional text to include (optional markdown)' - required: false - type: string - is_draft: - description: 'Create as draft release' + create_release: + description: "Create new release" required: false type: boolean default: false is_prerelease: - description: 'Mark as prerelease' + description: "Mark as pre-release" required: false type: boolean - default: true + default: false dry_run: - description: 'Dry run - generate release notes without creating release/tag' + description: "Dry run: never create tag/release, only generate notes + artifacts" required: false type: boolean default: false @@ -44,269 +36,269 @@ permissions: pull-requests: read jobs: - create-release: + build-linux-zh: + uses: ./.github/workflows/build-linux.yml + with: + game: GeneralsMD + preset: linux64-deploy + + build-macos-zh: + uses: ./.github/workflows/build-macos.yml + with: + game: GeneralsMD + preset: macos-vulkan + + prepare-release: runs-on: ubuntu-latest + needs: [build-linux-zh, build-macos-zh] steps: - name: Checkout repository uses: actions/checkout@v4 with: - fetch-depth: 0 # Full history for changelog generation + fetch-depth: 0 + fetch-tags: true - - name: Validate release version + - name: Validate release inputs run: | VERSION="${{ inputs.release_version }}" DRY_RUN="${{ inputs.dry_run }}" - + if [ -z "$VERSION" ]; then echo "ERROR: release_version is required" exit 1 fi - + if [ "$DRY_RUN" = "true" ]; then - echo "โœ“ DRY RUN MODE - tag validation skipped" - echo "Release version: $VERSION (not created)" + echo "Dry run enabled. Tag/release creation will be skipped." else if git show-ref --tags --verify --quiet "refs/tags/$VERSION"; then echo "ERROR: Tag $VERSION already exists" exit 1 fi - echo "Release version: $VERSION" fi - - name: Detect latest release + - name: Detect latest release tag id: latest run: | - LATEST=$(git tag -l "GeneralsX*" --sort=-version:refname --merged HEAD | head -1) - if [ -z "$LATEST" ]; then - echo "first_release=true" >> $GITHUB_OUTPUT - echo "latest_tag=" >> $GITHUB_OUTPUT + LATEST_TAG=$(git tag -l "GeneralsX*" --sort=-version:refname --merged HEAD | head -1) + if [ -z "$LATEST_TAG" ]; then + echo "latest_tag=" >> "$GITHUB_OUTPUT" + echo "latest_tag_date=" >> "$GITHUB_OUTPUT" + echo "first_release=true" >> "$GITHUB_OUTPUT" else - echo "first_release=false" >> $GITHUB_OUTPUT - echo "latest_tag=$LATEST" >> $GITHUB_OUTPUT + LATEST_TAG_DATE=$(git log -1 --format=%cI "$LATEST_TAG") + echo "latest_tag=$LATEST_TAG" >> "$GITHUB_OUTPUT" + echo "latest_tag_date=$LATEST_TAG_DATE" >> "$GITHUB_OUTPUT" + echo "first_release=false" >> "$GITHUB_OUTPUT" + fi + + - name: Download Linux bundle artifact + uses: actions/download-artifact@v4 + with: + name: linux-generalsxzh-linux64-bundle + path: artifacts/linux + + - name: Download macOS bundle artifact + uses: actions/download-artifact@v4 + with: + name: macos-generalsxzh-app + path: artifacts/macos + + - name: Normalize bundle files for release assets + id: assets + run: | + mkdir -p release-assets + + LINUX_TAR=$(find artifacts/linux -name "*.tar" | head -1) + if [ -z "$LINUX_TAR" ] || [ ! -f "$LINUX_TAR" ]; then + echo "ERROR: Linux bundle tar not found in artifacts/linux" + find artifacts/linux -maxdepth 3 -type f || true + exit 1 + fi + + mkdir -p /tmp/linux-bundle + tar -xf "$LINUX_TAR" -C /tmp/linux-bundle + ( + cd /tmp/linux-bundle + zip -r "$GITHUB_WORKSPACE/release-assets/linux-generalsxzh-linux64-bundle.zip" . + ) + + MAC_TAR=$(find artifacts/macos -name "*.tar" | head -1) + if [ -z "$MAC_TAR" ] || [ ! -f "$MAC_TAR" ]; then + echo "ERROR: macOS app tar not found in artifacts/macos" + find artifacts/macos -maxdepth 3 -type f || true + exit 1 fi - echo "Latest release tag: ${LATEST:-none}" - - name: Generate changelog + cp "$MAC_TAR" release-assets/GeneralsXZH-macos-arm64.app.tar + zip -j release-assets/macos-generalsxzh-app.tar.zip release-assets/GeneralsXZH-macos-arm64.app.tar + + echo "linux_asset=$GITHUB_WORKSPACE/release-assets/linux-generalsxzh-linux64-bundle.zip" >> "$GITHUB_OUTPUT" + echo "macos_asset=$GITHUB_WORKSPACE/release-assets/macos-generalsxzh-app.tar.zip" >> "$GITHUB_OUTPUT" + + - name: Build changelog from local PRs only id: changelog env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} LATEST_TAG: ${{ steps.latest.outputs.latest_tag }} + REPO: ${{ github.repository }} run: | - CHANGELOG_FILE=$(mktemp) - echo "changelog_file=$CHANGELOG_FILE" >> $GITHUB_OUTPUT - - # Get commit range - if [ -z "$LATEST_TAG" ]; then - COMMIT_RANGE="HEAD" - else + PR_LINES_FILE=$(mktemp) + PR_DATA_FILE=$(mktemp) + COMMIT_RANGE="HEAD" + + if [ -n "$LATEST_TAG" ]; then COMMIT_RANGE="${LATEST_TAG}..HEAD" fi - - echo "Generating changelog for: $COMMIT_RANGE" - - # Simple git log approach - get PR-based entries where possible - # git log with PR number extraction - git log $COMMIT_RANGE --pretty=format:"%s (%an)" --no-decorate | while IFS= read -r line; do - if [ -z "$line" ]; then continue; fi - - # Check if line contains a PR number - if [[ "$line" =~ \(#([0-9]+)\) ]]; then - pr_num="${BASH_REMATCH[1]}" - # Try to get PR author - pr_author=$(gh pr view "$pr_num" --json author --jq '.author.login' 2>/dev/null || echo "") - if [ -n "$pr_author" ]; then - # Extract message without author part - msg=$(echo "$line" | sed 's/ ([^)]*)$//') - msg=$(echo "$msg" | sed -E 's/ \(#[0-9]+\)$//') - echo "* ${msg} by @${pr_author} in https://github.com/${{ github.repository }}/pull/${pr_num}" >> "$CHANGELOG_FILE" - else - echo "* $line" >> "$CHANGELOG_FILE" - fi - else - echo "* $line" >> "$CHANGELOG_FILE" + + for SHA in $(git rev-list "$COMMIT_RANGE"); do + PR_JSON=$(gh api "repos/${REPO}/commits/${SHA}/pulls" 2>/dev/null || echo "[]") + PR_NUMBER=$(echo "$PR_JSON" | jq -r '.[0].number // empty') + + if [ -z "$PR_NUMBER" ]; then + continue fi + + PR_ENTRY=$(echo "$PR_JSON" | jq -r '.[0] | "\(.number)|\(.title)|\(.user.login)|\(.html_url)"') + echo "$PR_ENTRY" >> "$PR_DATA_FILE" done - - echo "Changelog entries created" - - name: Detect new contributors - id: contributors + if [ -s "$PR_DATA_FILE" ]; then + sort -u -t'|' -k1,1n "$PR_DATA_FILE" | while IFS='|' read -r NUMBER TITLE AUTHOR URL; do + [ -z "$NUMBER" ] && continue + echo "- ${TITLE} by @${AUTHOR} in ${URL}" >> "$PR_LINES_FILE" + done + fi + + if [ ! -s "$PR_LINES_FILE" ]; then + echo "- No pull requests found in this release range." >> "$PR_LINES_FILE" + fi + + echo "pr_lines_file=$PR_LINES_FILE" >> "$GITHUB_OUTPUT" + echo "pr_data_file=$PR_DATA_FILE" >> "$GITHUB_OUTPUT" + + - name: Detect new contributors from PR authors + id: new_contributors env: - LATEST_TAG: ${{ steps.latest.outputs.latest_tag }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + LATEST_TAG_DATE: ${{ steps.latest.outputs.latest_tag_date }} run: | - NEW_CONTRIBUTORS_FILE=$(mktemp) - echo "contributors_file=$NEW_CONTRIBUTORS_FILE" >> $GITHUB_OUTPUT - - if [ -z "$LATEST_TAG" ]; then - echo "First release - skipping new contributor detection" - touch "$NEW_CONTRIBUTORS_FILE" - else - # Get authors from previous releases - old_authors=$(git log "$LATEST_TAG" --pretty=format:"%an" 2>/dev/null | sort -u || true) - - # Get authors in new commits - new_authors=$(git log "${LATEST_TAG}..HEAD" --pretty=format:"%an" 2>/dev/null | sort -u || true) - - # Find new contributors - while IFS= read -r author; do - [ -z "$author" ] && continue - if ! printf '%s\n' "$old_authors" | grep -Fqx "$author"; then - echo "* ${author} made their first contribution" >> "$NEW_CONTRIBUTORS_FILE" - fi - done <<< "$new_authors" + CONTRIBUTORS_FILE=$(mktemp) + PR_DATA_FILE="${{ steps.changelog.outputs.pr_data_file }}" + + if [ ! -s "$PR_DATA_FILE" ]; then + echo "contributors_file=$CONTRIBUTORS_FILE" >> "$GITHUB_OUTPUT" + exit 0 fi - - name: Build release body - id: body + awk -F'|' '{print $3"|"$4}' "$PR_DATA_FILE" | sort -u | while IFS='|' read -r AUTHOR LOGIN_PR_URL; do + [ -z "$AUTHOR" ] && continue + + if [ -z "$LATEST_TAG_DATE" ]; then + echo "* @${AUTHOR} made their first contribution in ${LOGIN_PR_URL}" >> "$CONTRIBUTORS_FILE" + continue + fi + + PREV_COUNT=$(gh api "search/issues" \ + -f q="repo:${REPO} is:pr is:merged author:${AUTHOR} merged:<${LATEST_TAG_DATE}" \ + --jq '.total_count' 2>/dev/null || echo "0") + + if [ "$PREV_COUNT" = "0" ]; then + echo "* @${AUTHOR} made their first contribution in ${LOGIN_PR_URL}" >> "$CONTRIBUTORS_FILE" + fi + done + + echo "contributors_file=$CONTRIBUTORS_FILE" >> "$GITHUB_OUTPUT" + + - name: Build release notes markdown + id: notes env: - BUILD_NOTES: ${{ inputs.build_notes }} - KNOWN_ISSUES: ${{ inputs.known_issues }} - CUSTOM_TEXT: ${{ inputs.custom_text }} - CHANGELOG_FILE: ${{ steps.changelog.outputs.changelog_file }} - CONTRIBUTORS_FILE: ${{ steps.contributors.outputs.contributors_file }} + ADDITIONAL_NOTES: ${{ inputs.additional_notes }} LATEST_TAG: ${{ steps.latest.outputs.latest_tag }} - RELEASE_VERSION: ${{ inputs.release_version }} - REPO: ${{ github.repository }} + CURRENT_TAG: ${{ inputs.release_version }} + PR_LINES_FILE: ${{ steps.changelog.outputs.pr_lines_file }} + CONTRIBUTORS_FILE: ${{ steps.new_contributors.outputs.contributors_file }} run: | - BODY_FILE=$(mktemp) - echo "body_file=$BODY_FILE" >> $GITHUB_OUTPUT - + NOTES_FILE="release-assets/${{ inputs.release_version }}-notes.md" + mkdir -p release-assets + { - # Custom text if provided - if [ -n "$CUSTOM_TEXT" ]; then - echo "$CUSTOM_TEXT" - echo "" - echo "" - fi - - # Build notes if provided - if [ -n "$BUILD_NOTES" ]; then - echo "## Build Notes" - echo "" - echo "$BUILD_NOTES" - echo "" - echo "" - fi - - # Known issues if provided - if [ -n "$KNOWN_ISSUES" ]; then - echo "## Known Issues" - echo "" - echo "$KNOWN_ISSUES" - echo "" - echo "" - fi - - # Default beta warning - echo "> This is a **beta** release. Some bugs are still expected. If you run into any problems, please [open an issue](https://github.com/${REPO}/issues) so we can investigate." + echo "> This is a **beta** release. Some bugs are still expected. If you run into any problems, please [open an issue](https://github.com/fbraz3/GeneralsX/issues) so we can investigate." echo "" echo "# Install Instructions" echo "" - echo "https://github.com/${REPO}/blob/main/docs/BUILD/INSTALL_INSTRUCTIONS.md" + echo "https://github.com/fbraz3/GeneralsX/blob/main/docs/BUILD/INSTALL_INSTRUCTIONS.md" echo "" + + if [ -n "$ADDITIONAL_NOTES" ]; then + echo "## Additional Notes" + echo "" + echo "$ADDITIONAL_NOTES" + echo "" + fi + echo "## What's Changed" echo "" - - # Add changelog - if [ -f "$CHANGELOG_FILE" ] && [ -s "$CHANGELOG_FILE" ]; then - cat "$CHANGELOG_FILE" - else - echo "*No commits since latest release*" - fi - + cat "$PR_LINES_FILE" echo "" - - # Add new contributors if any - if [ -f "$CONTRIBUTORS_FILE" ] && [ -s "$CONTRIBUTORS_FILE" ]; then + + if [ -s "$CONTRIBUTORS_FILE" ]; then echo "## New Contributors" echo "" cat "$CONTRIBUTORS_FILE" echo "" fi - - # Full changelog link + if [ -n "$LATEST_TAG" ]; then - echo "**Full Changelog**: https://github.com/${REPO}/compare/${LATEST_TAG}...${RELEASE_VERSION}" + echo "**Full Changelog**: https://github.com/fbraz3/GeneralsX/compare/${LATEST_TAG}...${CURRENT_TAG}" fi - - } > "$BODY_FILE" - - echo "Release body generated" + } > "$NOTES_FILE" - - name: Preview release body - run: | - echo "=== Release Body Preview ===" - cat "${{ steps.body.outputs.body_file }}" - echo "" - echo "=== End Preview ===" - - - name: Save markdown for dry-run or review - if: success() - run: | - mkdir -p release-artifacts - cp "${{ steps.body.outputs.body_file }}" "release-artifacts/${{ inputs.release_version }}-notes.md" - echo "Release notes saved to release-artifacts/${{ inputs.release_version }}-notes.md" + echo "notes_file=$GITHUB_WORKSPACE/$NOTES_FILE" >> "$GITHUB_OUTPUT" - - name: Upload release notes (dry-run mode) - if: success() && inputs.dry_run == true + - name: Upload preview artifacts + if: success() && (inputs.dry_run == true || inputs.create_release == false) uses: actions/upload-artifact@v4 with: - name: release-notes-${{ inputs.release_version }} - path: release-artifacts/${{ inputs.release_version }}-notes.md + name: release-preview-${{ inputs.release_version }} + path: | + release-assets/*.md + release-assets/*.zip retention-days: 30 - - name: Create release - if: success() && inputs.dry_run == false + - name: Create GitHub release and upload assets + if: success() && inputs.dry_run == false && inputs.create_release == true env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - DRAFT_FLAG="" PRERELEASE_FLAG="" - NOTES_FILE="${{ steps.body.outputs.body_file }}" - - if [ "${{ inputs.is_draft }}" = "true" ]; then - DRAFT_FLAG="--draft" - fi - + if [ "${{ inputs.is_prerelease }}" = "true" ]; then PRERELEASE_FLAG="--prerelease" fi - + gh release create "${{ inputs.release_version }}" \ - $DRAFT_FLAG \ $PRERELEASE_FLAG \ --title "GeneralsX - ${{ inputs.release_version }}" \ - --notes-file "$NOTES_FILE" - - echo "โœ“ Release created successfully!" - echo "View at: https://github.com/${{ github.repository }}/releases/tag/${{ inputs.release_version }}" + --notes-file "${{ steps.notes.outputs.notes_file }}" \ + "${{ steps.assets.outputs.linux_asset }}" \ + "${{ steps.assets.outputs.macos_asset }}" - name: Summary run: | - if [ "${{ inputs.dry_run }}" = "true" ]; then - echo "## ๐Ÿงช Dry Run Completed" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "No release or tag was created. Review the release notes artifact above." >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### What Would Be Created" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "- **Tag**: \`${{ inputs.release_version }}\`" >> $GITHUB_STEP_SUMMARY - echo "- **Draft**: ${{ inputs.is_draft }}" >> $GITHUB_STEP_SUMMARY - echo "- **Prerelease**: ${{ inputs.is_prerelease }}" >> $GITHUB_STEP_SUMMARY - echo "- **Base Release**: ${{ steps.latest.outputs.latest_tag }}" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### Artifact" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "Release notes markdown: **\`${{ inputs.release_version }}-notes.md\`**" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "Download from this workflow's artifacts to preview, edit, and review." >> $GITHUB_STEP_SUMMARY + echo "## Release Pipeline Summary" >> "$GITHUB_STEP_SUMMARY" + echo "" >> "$GITHUB_STEP_SUMMARY" + echo "- Tag: ${{ inputs.release_version }}" >> "$GITHUB_STEP_SUMMARY" + echo "- Create release: ${{ inputs.create_release }}" >> "$GITHUB_STEP_SUMMARY" + echo "- Pre-release: ${{ inputs.is_prerelease }}" >> "$GITHUB_STEP_SUMMARY" + echo "- Dry run: ${{ inputs.dry_run }}" >> "$GITHUB_STEP_SUMMARY" + echo "- Linux asset: linux-generalsxzh-linux64-bundle.zip" >> "$GITHUB_STEP_SUMMARY" + echo "- macOS asset: macos-generalsxzh-app.tar.zip" >> "$GITHUB_STEP_SUMMARY" + echo "" >> "$GITHUB_STEP_SUMMARY" + + if [ "${{ inputs.dry_run }}" = "true" ] || [ "${{ inputs.create_release }}" = "false" ]; then + echo "No GitHub release was created. Download preview artifacts from this run." >> "$GITHUB_STEP_SUMMARY" else - echo "## โœ… Release Created" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "- **Tag**: ${{ inputs.release_version }}" >> $GITHUB_STEP_SUMMARY - echo "- **Draft**: ${{ inputs.is_draft }}" >> $GITHUB_STEP_SUMMARY - echo "- **Prerelease**: ${{ inputs.is_prerelease }}" >> $GITHUB_STEP_SUMMARY - echo "- **Latest Release**: ${{ steps.latest.outputs.latest_tag }}" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**View Release**: https://github.com/${{ github.repository }}/releases/tag/${{ inputs.release_version }}" >> $GITHUB_STEP_SUMMARY + echo "Release created and assets attached." >> "$GITHUB_STEP_SUMMARY" fi diff --git a/docs/DEV_BLOG/2026-04-DIARY.md b/docs/DEV_BLOG/2026-04-DIARY.md index 7baaad4f518..ef9661ef3d9 100644 --- a/docs/DEV_BLOG/2026-04-DIARY.md +++ b/docs/DEV_BLOG/2026-04-DIARY.md @@ -2,6 +2,39 @@ --- +## 2026-04-07 (SESSION 110): Rework release pipeline to build bundles and publish optional release + +Reworked the release workflow to match the expected operator flow: run platform builds, collect bundles, generate fixed-format notes from local PRs, and only publish when explicitly requested. + +What was changed: +- Release workflow redesign: + - `.github/workflows/release.yml` + - Simplified inputs to: `release_version`, `additional_notes`, `create_release`, `is_prerelease`, `dry_run`. + - Set defaults to unchecked for `create_release` and `is_prerelease`. + - Added job-level build orchestration via reusable workflows: + - Linux Zero Hour build (`build-linux.yml`, `GeneralsMD`, `linux64-deploy`) + - macOS Zero Hour build (`build-macos.yml`, `GeneralsMD`, `macos-vulkan`) + - Downloaded build artifacts from both jobs and normalized release assets to: + - `linux-generalsxzh-linux64-bundle.zip` + - `macos-generalsxzh-app.tar.zip` + - Implemented release-note generation with fixed header block plus optional `Additional Notes`. + - Implemented changelog generation from PRs associated to commits in local repo (`fbraz3/GeneralsX`) to avoid upstream TheSuperHackers PR leakage. + - Implemented new contributor detection with `@username` + PR URL format. + - Added preview artifact upload when `dry_run=true` or `create_release=false`. + - Release creation now happens only when `create_release=true` and `dry_run=false`. +- Documentation update: + - `docs/WORKDIR/support/RELEASE_PIPELINE.md` + - Rewritten to reflect new inputs, behavior, output asset names, and publishing flow. + +Why: +- Align workflow UX with expected release process and avoid accidental publish/tag creation. +- Ensure release notes and contributor sections follow the exact target markdown format. +- Guarantee release artifacts are generated from fresh Linux/macOS build jobs in the same pipeline execution. + +Validation: +- `get_errors` returned no diagnostics for `.github/workflows/release.yml`. +- Workflow input defaults and conditional paths validated by inspection (`create_release=false`, `is_prerelease=false`). + ## 2026-04-07 (SESSION 109): TheSuperHackers upstream sync with cross-platform preservation Performed a full upstream sync merge from `thesuperhackers/main` into branch `thesuperhackers-sync-04-07-2026` with conflict-by-conflict reconciliation to preserve GeneralsX cross-platform behavior. diff --git a/docs/WORKDIR/support/RELEASE_PIPELINE.md b/docs/WORKDIR/support/RELEASE_PIPELINE.md index d88d6bc1212..276a4bb8404 100644 --- a/docs/WORKDIR/support/RELEASE_PIPELINE.md +++ b/docs/WORKDIR/support/RELEASE_PIPELINE.md @@ -1,247 +1,70 @@ # Release Pipeline -Automated GitHub Actions workflow for creating GeneralsX releases with automatic changelog generation. - -## Features - -โœ… **Manual Dispatch** โ€” Trigger releases on-demand from GitHub Actions UI -โœ… **Auto Changelog** โ€” Generates changelog from commits since latest release -โœ… **PR Linking** โ€” Automatically links PRs to changelog entries -โœ… **New Contributors** โ€” Detects and credits first-time contributors -โœ… **Build/Known Issues Notes** โ€” Add structured release notes sections -โœ… **Custom Text** โ€” Add personalized release notes -โœ… **Draft/Prerelease Options** โ€” Mark releases appropriately - -## Quick Start - -1. Go to **Actions** tab โ†’ **Release Pipeline** -2. Click **Run workflow** button -3. Fill in the required field: - - **release_version**: Tag name (e.g., `GeneralsX-Beta-3`) -4. Optionally fill in sections: - - **build_notes**: What changed in this build - - **known_issues**: Known issues in this release - - **custom_text**: Additional markdown -5. Configure flags if needed: - - **is_draft**: Leave unchecked for public release - - **is_prerelease**: Check to mark as prerelease (default: checked) -6. Click **Run workflow** - -## Inputs Reference +This workflow runs Linux and macOS builds, collects Zero Hour bundles, generates release notes from local pull requests, and optionally creates a GitHub release. + +## Inputs | Input | Type | Default | Description | |-------|------|---------|-------------| -| `release_version` | string | โ€” | Release tag name (e.g., `GeneralsX-Beta-3`) | -| `build_notes` | string | โ€” | Build notes section (markdown) | -| `known_issues` | string | โ€” | Known issues section (markdown) | -| `custom_text` | string | โ€” | Additional text to include (markdown) | -| `is_draft` | boolean | false | Create as draft (hidden from releases page) | -| `is_prerelease` | boolean | true | Mark as prerelease (not as latest) | -| `dry_run` | boolean | false | Test logic without creating release (no tag created) | +| `release_version` | string | โ€” | Target tag/version (for example: `GeneralsX-Beta-3`) | +| `additional_notes` | string | empty | Optional extra notes section | +| `create_release` | boolean | false | When true, creates a GitHub release and uploads assets | +| `is_prerelease` | boolean | false | When true, marks the release as pre-release | +| `dry_run` | boolean | false | Forces no release creation; only generates notes and artifacts | -## Examples +## Behavior -### Basic Release (just version) +1. Runs Linux build for Zero Hour (`GeneralsMD`, `linux64-deploy`). +2. Runs macOS build for Zero Hour (`GeneralsMD`, `macos-vulkan`). +3. Downloads generated bundle artifacts from both jobs. +4. Produces release assets: + - `linux-generalsxzh-linux64-bundle.zip` + - `macos-generalsxzh-app.tar.zip` +5. Generates release notes with fixed header text plus: + - `## Additional Notes` (only if provided) + - `## What's Changed` + - `## New Contributors` (when applicable) + - `**Full Changelog**` (when a previous tag exists) +6. Uses only pull requests associated with commits in `fbraz3/GeneralsX` (ignores upstream TheSuperHackers PRs). +7. If `dry_run=true` or `create_release=false`, uploads preview artifacts instead of creating a release. +8. Creates GitHub release only when `create_release=true` and `dry_run=false`. -``` -release_version: GeneralsX-Beta-3 -``` +## Notes Format -### Release with Build Notes +Fixed block: -``` -release_version: GeneralsX-Beta-3 -build_notes: | - - Fixed critical multiplayer desync issue - - Improved Linux performance by 20% - - Updated DXVK to v2.6 -``` +```markdown +> This is a **beta** release. Some bugs are still expected. If you run into any problems, please [open an issue](https://github.com/fbraz3/GeneralsX/issues) so we can investigate. -### Release with Known Issues +# Install Instructions -``` -release_version: GeneralsX-Beta-3 -build_notes: | - - Fixed renderer crashes on macOS - - Improved audio synchronization -known_issues: | - - Replays from Beta-2 are not compatible - - Some mods may require recompiling +https://github.com/fbraz3/GeneralsX/blob/main/docs/BUILD/INSTALL_INSTRUCTIONS.md ``` -### Full Featured Release +What's changed format: -``` -release_version: GeneralsX-Beta-3 -build_notes: | - - Fixed critical multiplayer desync - - Updated DXVK to v2.6 - - Improved macOS bundle deployment -known_issues: | - - Replays from Beta-2 not compatible - - Some mods may need recompilation -custom_text: | - ## Highlights - - This release focuses on stability and performance improvements. -is_draft: false -is_prerelease: true -``` +```markdown +## What's Changed -### Dry Run - Test Release Notes - -``` -release_version: GeneralsX-Beta-3 -build_notes: | - - Fixed critical issues -known_issues: | - - Some edge cases remain -dry_run: true +- $COMMIT_TITLE by @$AUTHOR in $PULL_REQUEST_URL ``` -**Dry Run Behavior**: -- No tag is created -- No release is published -- Release notes markdown is generated as an artifact -- Download the artifact to review before publishing for real -- Perfect for testing changelog logic and reviewing notes before commit - -## Workflow Behavior - -1. **Validation**: Ensures version doesn't already exist (skipped in dry-run) -2. **Detection**: Finds latest release tag (GeneralsX-Beta-2, etc.) -3. **Changelog Generation**: - - Extracts commits since latest release using `git log` - - Finds associated PRs in commit messages - - Groups entries and adds PR author credits -4. **New Contributors**: Detects first-time contributors by comparing author lists -5. **Body Assembly**: - - Prepends custom text if provided - - Adds build notes section if provided - - Adds known issues section if provided - - Includes beta warning - - Includes install instructions link - - Lists "What's Changed" with PR links - - Credits new contributors - - Links to full changelog comparison -6. **Dry-Run Check**: - - If `dry_run: true` โ†’ skip release creation, generate markdown artifact only - - If `dry_run: false` โ†’ proceed to release creation -7. **Release Creation** (if not dry-run): - - Uses `gh release create` to publish release -8. **Summary**: Posts results to workflow summary (different messages for dry-run vs real release) - -## About Artifacts - -Currently, artifacts must be: -- Downloaded manually from successful build workflow artifacts -- Attached to the release manually via GitHub UI release edit page - -To attach artifacts after release creation: -1. Go to the release page -2. Click **Edit** button -3. Scroll to "Attachments" section -4. Drag-drop or click to upload files - -Future enhancement: Automatically download and attach artifacts from latest successful builds. - -## Dry Run Mode - -Use dry-run to test the release logic without creating a tag or publishing a release. - -**What Happens in Dry Run**: -- โœ“ Changelog is generated -- โœ“ Release notes markdown is created -- โœ“ Markdown file is uploaded as a workflow artifact -- โœ— No tag is created -- โœ— No release is published -- โœ— No GitHub API calls that create/modify data - -**Workflow**: -1. Run workflow with `dry_run: true` -2. Workflow completes (summary shows "๐Ÿงช Dry Run Completed") -3. Download the markdown artifact from workflow -4. Review release notes in your editor -5. If satisfied, run workflow again with `dry_run: false` to publish for real - -**Artifact Location**: -- After dry-run completes, go to workflow run page -- Scroll to "Artifacts" section -- Download `release-notes-GeneralsX-Beta-3` (or your version) -- File is named `GeneralsX-Beta-3-notes.md` - -## Changelog Format - -Each changelog entry follows this pattern: +New contributors format: -``` -* fix(component): description by @author in https://github.com/fbraz3/GeneralsX/pull/123 -``` - -For commits without associated PRs: +```markdown +## New Contributors -``` -* fix(component): description +* @$USERNAME made their first contribution in $PULL_REQUEST_URL ``` -## New Contributor Detection +Full changelog format: -The workflow attempts to identify first-time contributors by: -1. Comparing author lists before/after the latest release -2. Selecting names that did not exist before the latest release -3. Creating safe contributor credit lines without exposing email-derived data - -Example output: - -``` -## New Contributors -* NewContributor made their first contribution +```markdown +**Full Changelog**: https://github.com/fbraz3/GeneralsX/compare/$LAST_TAG...$CURRENT_TAG ``` -## Troubleshooting - -### "Tag already exists" -The version you specified already has a release. Use a different tag name. - -Note: This error won't occur in `dry_run: true` mode since no tag validation happens. - -### Changelog shows but PR links are missing -- Ensure commits reference PR numbers in message (e.g., `(#123)`) -- If PR numbers are not in message, manually add PR links to release notes -- Future enhancement: better PR detection patterns - -### No new contributors detected -This is expected if: -- No new authors since latest release -- Or all changes were made by contributors already present before the latest release - -### Want to preview before publishing? -Use the dry-run mode! -1. Run with `dry_run: true` -2. Workflow artifacts will contain the markdown -3. Download and review -4. If ok, run again with `dry_run: false` - -## Manual Post-Release Adjustments - -After the workflow completes, you can: - -1. **Edit release notes** directly in GitHub UI if needed -2. **Upload artifacts** by dragging/dropping them on the release page -3. **Publish draft** by unchecking "Set as a draft" - -## Notes - -- All input text fields support **Markdown formatting** -- Inputs like `build_notes`, `known_issues`, and `custom_text` are optional -- The beta warning is always included automatically -- Install instructions link points to `main` branch docs -- Release created via GitHub's `gh` CLI tool (requires GitHub token) - -## Future Enhancements +## Recommended Usage -- [ ] Automatic artifact attachment from build workflows -- [ ] Contributor avatars/links in new contributors section -- [ ] Per-category changelog grouping (features, bugfixes, performance, etc.) -- [ ] Better PR detection using GitHub API search -- [ ] Changelog caching to avoid GitHub API rate limits on large histories +1. First run with `create_release=false` to validate output artifacts. +2. Review generated markdown and zip files from workflow artifacts. +3. Run again with `create_release=true` (and optionally `is_prerelease=true`) to publish. From 37667a3eddc90aea229afd39d3f46c1d767cc639 Mon Sep 17 00:00:00 2001 From: Felipe Keller Braz Date: Tue, 7 Apr 2026 17:39:20 -0300 Subject: [PATCH 2/6] feat(release): include Generals base bundles in release pipeline - add Linux Generals build job to release workflow - add macOS Generals build job to release workflow - download all four build artifacts (ZH + Generals) - normalize and package all four release assets - attach Generals and ZH assets on release creation - update workflow summary with full asset list - update release pipeline documentation for new scope --- .github/workflows/release.yml | 63 +++++++++++++++++++++++- docs/WORKDIR/support/RELEASE_PIPELINE.md | 10 ++-- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f48de26573d..db6e22a1a96 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,15 +42,34 @@ jobs: game: GeneralsMD preset: linux64-deploy + build-linux-generals: + uses: ./.github/workflows/build-linux.yml + with: + game: Generals + preset: linux64-deploy + build-macos-zh: uses: ./.github/workflows/build-macos.yml with: game: GeneralsMD preset: macos-vulkan + build-macos-generals: + uses: ./.github/workflows/build-macos.yml + with: + game: Generals + preset: macos-vulkan + + build-windows-zh: + uses: ./.github/workflows/build-windows.yml + if: true == false # Temporarily disable Windows build until it's implemented + with: + game: GeneralsMD + preset: win64-modern + prepare-release: runs-on: ubuntu-latest - needs: [build-linux-zh, build-macos-zh] + needs: [build-linux-zh, build-linux-generals, build-macos-zh, build-macos-generals] steps: - name: Checkout repository uses: actions/checkout@v4 @@ -98,12 +117,24 @@ jobs: name: linux-generalsxzh-linux64-bundle path: artifacts/linux + - name: Download Linux Generals bundle artifact + uses: actions/download-artifact@v4 + with: + name: linux-generalsx-linux64-bundle + path: artifacts/linux-generals + - name: Download macOS bundle artifact uses: actions/download-artifact@v4 with: name: macos-generalsxzh-app path: artifacts/macos + - name: Download macOS Generals bundle artifact + uses: actions/download-artifact@v4 + with: + name: macos-generalsx-app + path: artifacts/macos-generals + - name: Normalize bundle files for release assets id: assets run: | @@ -123,6 +154,20 @@ jobs: zip -r "$GITHUB_WORKSPACE/release-assets/linux-generalsxzh-linux64-bundle.zip" . ) + LINUX_GENERALS_TAR=$(find artifacts/linux-generals -name "*.tar" | head -1) + if [ -z "$LINUX_GENERALS_TAR" ] || [ ! -f "$LINUX_GENERALS_TAR" ]; then + echo "ERROR: Linux Generals bundle tar not found in artifacts/linux-generals" + find artifacts/linux-generals -maxdepth 3 -type f || true + exit 1 + fi + + mkdir -p /tmp/linux-generals-bundle + tar -xf "$LINUX_GENERALS_TAR" -C /tmp/linux-generals-bundle + ( + cd /tmp/linux-generals-bundle + zip -r "$GITHUB_WORKSPACE/release-assets/linux-generalsx-linux64-bundle.zip" . + ) + MAC_TAR=$(find artifacts/macos -name "*.tar" | head -1) if [ -z "$MAC_TAR" ] || [ ! -f "$MAC_TAR" ]; then echo "ERROR: macOS app tar not found in artifacts/macos" @@ -133,7 +178,19 @@ jobs: cp "$MAC_TAR" release-assets/GeneralsXZH-macos-arm64.app.tar zip -j release-assets/macos-generalsxzh-app.tar.zip release-assets/GeneralsXZH-macos-arm64.app.tar + MAC_GENERALS_TAR=$(find artifacts/macos-generals -name "*.tar" | head -1) + if [ -z "$MAC_GENERALS_TAR" ] || [ ! -f "$MAC_GENERALS_TAR" ]; then + echo "ERROR: macOS Generals app tar not found in artifacts/macos-generals" + find artifacts/macos-generals -maxdepth 3 -type f || true + exit 1 + fi + + cp "$MAC_GENERALS_TAR" release-assets/GeneralsX-macos-arm64.app.tar + zip -j release-assets/macos-generalsx-app.tar.zip release-assets/GeneralsX-macos-arm64.app.tar + + echo "linux_generals_asset=$GITHUB_WORKSPACE/release-assets/linux-generalsx-linux64-bundle.zip" >> "$GITHUB_OUTPUT" echo "linux_asset=$GITHUB_WORKSPACE/release-assets/linux-generalsxzh-linux64-bundle.zip" >> "$GITHUB_OUTPUT" + echo "macos_generals_asset=$GITHUB_WORKSPACE/release-assets/macos-generalsx-app.tar.zip" >> "$GITHUB_OUTPUT" echo "macos_asset=$GITHUB_WORKSPACE/release-assets/macos-generalsxzh-app.tar.zip" >> "$GITHUB_OUTPUT" - name: Build changelog from local PRs only @@ -282,7 +339,9 @@ jobs: $PRERELEASE_FLAG \ --title "GeneralsX - ${{ inputs.release_version }}" \ --notes-file "${{ steps.notes.outputs.notes_file }}" \ + "${{ steps.assets.outputs.linux_generals_asset }}" \ "${{ steps.assets.outputs.linux_asset }}" \ + "${{ steps.assets.outputs.macos_generals_asset }}" \ "${{ steps.assets.outputs.macos_asset }}" - name: Summary @@ -293,7 +352,9 @@ jobs: echo "- Create release: ${{ inputs.create_release }}" >> "$GITHUB_STEP_SUMMARY" echo "- Pre-release: ${{ inputs.is_prerelease }}" >> "$GITHUB_STEP_SUMMARY" echo "- Dry run: ${{ inputs.dry_run }}" >> "$GITHUB_STEP_SUMMARY" + echo "- Linux asset (Generals): linux-generalsx-linux64-bundle.zip" >> "$GITHUB_STEP_SUMMARY" echo "- Linux asset: linux-generalsxzh-linux64-bundle.zip" >> "$GITHUB_STEP_SUMMARY" + echo "- macOS asset (Generals): macos-generalsx-app.tar.zip" >> "$GITHUB_STEP_SUMMARY" echo "- macOS asset: macos-generalsxzh-app.tar.zip" >> "$GITHUB_STEP_SUMMARY" echo "" >> "$GITHUB_STEP_SUMMARY" diff --git a/docs/WORKDIR/support/RELEASE_PIPELINE.md b/docs/WORKDIR/support/RELEASE_PIPELINE.md index 276a4bb8404..40650b83436 100644 --- a/docs/WORKDIR/support/RELEASE_PIPELINE.md +++ b/docs/WORKDIR/support/RELEASE_PIPELINE.md @@ -1,6 +1,6 @@ # Release Pipeline -This workflow runs Linux and macOS builds, collects Zero Hour bundles, generates release notes from local pull requests, and optionally creates a GitHub release. +This workflow runs Linux and macOS builds for Zero Hour and Generals base, collects bundles, generates release notes from local pull requests, and optionally creates a GitHub release. ## Inputs @@ -14,11 +14,13 @@ This workflow runs Linux and macOS builds, collects Zero Hour bundles, generates ## Behavior -1. Runs Linux build for Zero Hour (`GeneralsMD`, `linux64-deploy`). -2. Runs macOS build for Zero Hour (`GeneralsMD`, `macos-vulkan`). -3. Downloads generated bundle artifacts from both jobs. +1. Runs Linux builds for Zero Hour and Generals base (`linux64-deploy`). +2. Runs macOS builds for Zero Hour and Generals base (`macos-vulkan`). +3. Downloads generated bundle artifacts from all platform/game jobs. 4. Produces release assets: + - `linux-generalsx-linux64-bundle.zip` - `linux-generalsxzh-linux64-bundle.zip` + - `macos-generalsx-app.tar.zip` - `macos-generalsxzh-app.tar.zip` 5. Generates release notes with fixed header text plus: - `## Additional Notes` (only if provided) From 6aa305da531d768b6bc7c72589df5384abe577b2 Mon Sep 17 00:00:00 2001 From: Felipe Keller Braz Date: Tue, 7 Apr 2026 18:01:39 -0300 Subject: [PATCH 3/6] fix(release): align permissions for reusable linux build workflow --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index db6e22a1a96..a05857cd31c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,7 +33,7 @@ concurrency: permissions: contents: write - pull-requests: read + pull-requests: write jobs: build-linux-zh: @@ -69,7 +69,7 @@ jobs: prepare-release: runs-on: ubuntu-latest - needs: [build-linux-zh, build-linux-generals, build-macos-zh, build-macos-generals] + needs: [build-linux-zh, build-linux-generals, build-macos-zh, build-macos-generals, build-windows-zh] steps: - name: Checkout repository uses: actions/checkout@v4 From 2fdc09d7225ed47554d5fef98f11fa045a4b57ed Mon Sep 17 00:00:00 2001 From: Felipe Keller Braz Date: Tue, 7 Apr 2026 20:32:39 -0300 Subject: [PATCH 4/6] fix(release): keep dry-run prepare path independent from disabled windows placeholder --- .github/workflows/release.yml | 9 +-------- docs/DEV_BLOG/2026-04-DIARY.md | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a05857cd31c..2fe5bd5e060 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,16 +60,9 @@ jobs: game: Generals preset: macos-vulkan - build-windows-zh: - uses: ./.github/workflows/build-windows.yml - if: true == false # Temporarily disable Windows build until it's implemented - with: - game: GeneralsMD - preset: win64-modern - prepare-release: runs-on: ubuntu-latest - needs: [build-linux-zh, build-linux-generals, build-macos-zh, build-macos-generals, build-windows-zh] + needs: [build-linux-zh, build-linux-generals, build-macos-zh, build-macos-generals] steps: - name: Checkout repository uses: actions/checkout@v4 diff --git a/docs/DEV_BLOG/2026-04-DIARY.md b/docs/DEV_BLOG/2026-04-DIARY.md index ef9661ef3d9..8e41615b7a6 100644 --- a/docs/DEV_BLOG/2026-04-DIARY.md +++ b/docs/DEV_BLOG/2026-04-DIARY.md @@ -2,6 +2,23 @@ --- +## 2026-04-07 (SESSION 111): Fix dry-run flow to execute full release preparation + +Fixed a workflow control issue where `prepare-release` could be skipped even in dry-run due to dependency on a disabled Windows placeholder job. + +What was changed: +- `.github/workflows/release.yml` +- Updated `prepare-release.needs` to depend only on active Linux/macOS jobs. +- Kept the Windows reusable workflow placeholder disabled, but removed it from release-preparation blocking path. + +Why: +- Dry-run must execute full preparation (artifact collection + notes generation) and skip only GitHub release creation. +- A skipped dependency in `needs` prevented `prepare-release` from running as expected. + +Validation: +- YAML diagnostics clean (`get_errors` reports no workflow errors). +- Conditional logic preserved: only `Create GitHub release and upload assets` is skipped in dry-run. + ## 2026-04-07 (SESSION 110): Rework release pipeline to build bundles and publish optional release Reworked the release workflow to match the expected operator flow: run platform builds, collect bundles, generate fixed-format notes from local PRs, and only publish when explicitly requested. From 1fe17e5eccd3c6d5796befb9e74bb17989b813a0 Mon Sep 17 00:00:00 2001 From: Felipe Keller Braz Date: Tue, 7 Apr 2026 21:50:48 -0300 Subject: [PATCH 5/6] fix(release): keep dry-run preview lightweight with notes txt only --- .github/workflows/release.yml | 31 ++++++++++++++++++++---- docs/DEV_BLOG/2026-04-DIARY.md | 21 ++++++++++++++++ docs/WORKDIR/support/RELEASE_PIPELINE.md | 5 ++++ 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2fe5bd5e060..6417b29e913 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -130,6 +130,8 @@ jobs: - name: Normalize bundle files for release assets id: assets + env: + DRY_RUN: ${{ inputs.dry_run }} run: | mkdir -p release-assets @@ -178,6 +180,15 @@ jobs: exit 1 fi + if [ "$DRY_RUN" = "true" ]; then + echo "Dry run enabled: skipping zip normalization to avoid large preview artifacts." + echo "linux_generals_asset=" >> "$GITHUB_OUTPUT" + echo "linux_asset=" >> "$GITHUB_OUTPUT" + echo "macos_generals_asset=" >> "$GITHUB_OUTPUT" + echo "macos_asset=" >> "$GITHUB_OUTPUT" + exit 0 + fi + cp "$MAC_GENERALS_TAR" release-assets/GeneralsX-macos-arm64.app.tar zip -j release-assets/macos-generalsx-app.tar.zip release-assets/GeneralsX-macos-arm64.app.tar @@ -271,6 +282,7 @@ jobs: CONTRIBUTORS_FILE: ${{ steps.new_contributors.outputs.contributors_file }} run: | NOTES_FILE="release-assets/${{ inputs.release_version }}-notes.md" + NOTES_TXT_FILE="release-assets/${{ inputs.release_version }}-notes.txt" mkdir -p release-assets { @@ -305,16 +317,25 @@ jobs: fi } > "$NOTES_FILE" + cp "$NOTES_FILE" "$NOTES_TXT_FILE" + echo "notes_file=$GITHUB_WORKSPACE/$NOTES_FILE" >> "$GITHUB_OUTPUT" + echo "notes_txt_file=$GITHUB_WORKSPACE/$NOTES_TXT_FILE" >> "$GITHUB_OUTPUT" + + - name: Upload dry-run release description + if: success() && inputs.dry_run == true + uses: actions/upload-artifact@v4 + with: + name: release-preview-${{ inputs.release_version }} + path: release-assets/${{ inputs.release_version }}-notes.txt + retention-days: 30 - - name: Upload preview artifacts - if: success() && (inputs.dry_run == true || inputs.create_release == false) + - name: Upload release description preview + if: success() && inputs.dry_run == false && inputs.create_release == false uses: actions/upload-artifact@v4 with: name: release-preview-${{ inputs.release_version }} - path: | - release-assets/*.md - release-assets/*.zip + path: release-assets/${{ inputs.release_version }}-notes.txt retention-days: 30 - name: Create GitHub release and upload assets diff --git a/docs/DEV_BLOG/2026-04-DIARY.md b/docs/DEV_BLOG/2026-04-DIARY.md index 8e41615b7a6..0e0b80e7ea1 100644 --- a/docs/DEV_BLOG/2026-04-DIARY.md +++ b/docs/DEV_BLOG/2026-04-DIARY.md @@ -2,6 +2,27 @@ --- +## 2026-04-07 (SESSION 112): Make dry-run preview lightweight (notes txt only) + +Adjusted release workflow dry-run behavior to avoid generating/uploading large preview bundles. + +What was changed: +- `.github/workflows/release.yml` +- In dry-run mode, keep build/download/validation and notes generation, but skip normalized zip creation. +- Added dedicated preview upload for `release-assets/-notes.txt` only. +- Kept real release path unchanged (`create_release=true` and `dry_run=false`) with full asset attachment. +- Added `notes.txt` output alongside `notes.md` for preview-focused runs. +- `docs/WORKDIR/support/RELEASE_PIPELINE.md` + - documented that dry-run uploads only the release description txt file. + +Why: +- Preview runs should validate pipeline logic without producing large artifacts. +- Requested UX: quick dry-run output focused on release text review. + +Validation: +- YAML diagnostics clean (`get_errors` reports no workflow errors). +- Dry-run now uploads a lightweight text artifact instead of hundreds of MB. + ## 2026-04-07 (SESSION 111): Fix dry-run flow to execute full release preparation Fixed a workflow control issue where `prepare-release` could be skipped even in dry-run due to dependency on a disabled Windows placeholder job. diff --git a/docs/WORKDIR/support/RELEASE_PIPELINE.md b/docs/WORKDIR/support/RELEASE_PIPELINE.md index 40650b83436..845ea1a5552 100644 --- a/docs/WORKDIR/support/RELEASE_PIPELINE.md +++ b/docs/WORKDIR/support/RELEASE_PIPELINE.md @@ -31,6 +31,11 @@ This workflow runs Linux and macOS builds for Zero Hour and Generals base, colle 7. If `dry_run=true` or `create_release=false`, uploads preview artifacts instead of creating a release. 8. Creates GitHub release only when `create_release=true` and `dry_run=false`. +Dry-run preview policy: +- Generates only one small preview file: `${release_version}-notes.txt`. +- Does not generate normalized zip assets for preview upload. +- Still validates build/download steps and notes generation logic. + ## Notes Format Fixed block: From f6cf8c13c938ca820d3650d5667428e95be704f1 Mon Sep 17 00:00:00 2001 From: Felipe Keller Braz Date: Tue, 7 Apr 2026 22:54:23 -0300 Subject: [PATCH 6/6] fix(release): restrict changelog to local repository PRs --- .github/workflows/release.yml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6417b29e913..66b50fe71ea 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -214,14 +214,19 @@ jobs: for SHA in $(git rev-list "$COMMIT_RANGE"); do PR_JSON=$(gh api "repos/${REPO}/commits/${SHA}/pulls" 2>/dev/null || echo "[]") - PR_NUMBER=$(echo "$PR_JSON" | jq -r '.[0].number // empty') - if [ -z "$PR_NUMBER" ]; then - continue + # Keep only PRs that belong to this repository (exclude upstream PR URLs). + PR_ENTRY=$(echo "$PR_JSON" | jq -r --arg REPO "$REPO" ' + map(select((.base.repo.full_name // "") == $REPO and (.html_url // "" | startswith("https://github.com/" + $REPO + "/pull/")))) + | sort_by(.number) + | reverse + | .[0] + | if . == null then empty else "\(.number)|\(.title)|\(.user.login)|\(.html_url)" end + ') + + if [ -n "$PR_ENTRY" ]; then + echo "$PR_ENTRY" >> "$PR_DATA_FILE" fi - - PR_ENTRY=$(echo "$PR_JSON" | jq -r '.[0] | "\(.number)|\(.title)|\(.user.login)|\(.html_url)"') - echo "$PR_ENTRY" >> "$PR_DATA_FILE" done if [ -s "$PR_DATA_FILE" ]; then