Nightly Release v3 #459
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Nightly Release v3 | |
| on: | |
| schedule: | |
| - cron: '0 15 * * *' # 3 PM UTC daily | |
| workflow_dispatch: | |
| inputs: | |
| force_release: | |
| description: 'Force release even if no changes detected' | |
| required: false | |
| default: false | |
| type: boolean | |
| dry_run: | |
| description: 'Run in dry-run mode (no actual release)' | |
| required: false | |
| default: true | |
| type: boolean | |
| release_version: | |
| description: 'Optional explicit version for an ad-hoc release (e.g. v3.0.0-beta.8)' | |
| required: false | |
| default: '' | |
| type: string | |
| jobs: | |
| nightly-release: | |
| runs-on: ubuntu-latest | |
| if: github.repository == 'wailsapp/wails' | |
| env: | |
| GOWORK: "off" | |
| permissions: | |
| contents: write | |
| pull-requests: read | |
| actions: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: master | |
| fetch-depth: 0 | |
| token: ${{ secrets.WAILS_REPO_TOKEN || github.token }} | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.25' | |
| cache: true | |
| cache-dependency-path: 'v3/go.sum' | |
| - name: Install Task | |
| uses: arduino/setup-task@v2 | |
| with: | |
| version: 3.x | |
| repo-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Git | |
| run: | | |
| git config --global user.name "github-actions[bot]" | |
| git config --global user.email "github-actions[bot]@users.noreply.github.com" | |
| # Configure git to use the token for authentication | |
| git config --global url."https://x-access-token:${{ secrets.WAILS_REPO_TOKEN || github.token }}@github.com/".insteadOf "https://github.com/" | |
| - name: Check for existing release tag | |
| id: check_tag | |
| run: | | |
| if git describe --tags --exact-match HEAD 2>/dev/null; then | |
| echo "has_tag=true" >> $GITHUB_OUTPUT | |
| echo "tag=$(git describe --tags --exact-match HEAD)" >> $GITHUB_OUTPUT | |
| else | |
| echo "has_tag=false" >> $GITHUB_OUTPUT | |
| echo "tag=" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Check for unreleased changelog content | |
| id: changelog_check | |
| run: | | |
| echo "π Checking UNRELEASED_CHANGELOG.md for content..." | |
| # Run the release script in check mode to see if there's content | |
| cd v3/tasks/release | |
| # Use the release script itself to check for content. The script uses | |
| # exit status 1 for the expected "no content" result, so preserve that | |
| # result while allowing read/parse failures to fail this workflow. | |
| set +e | |
| CHECK_OUTPUT=$(go run release.go --check-only 2>&1) | |
| CHECK_STATUS=$? | |
| set -e | |
| if [ "$CHECK_STATUS" -eq 0 ]; then | |
| echo "has_unreleased_content=true" >> $GITHUB_OUTPUT | |
| echo "β Found unreleased changelog content" | |
| elif [ "$CHECK_STATUS" -eq 1 ] && grep -Fq "No unreleased changelog content found." <<< "$CHECK_OUTPUT"; then | |
| echo "has_unreleased_content=false" >> $GITHUB_OUTPUT | |
| echo "βΉοΈ No unreleased changelog content found" | |
| else | |
| echo "$CHECK_OUTPUT" >&2 | |
| echo "β Changelog check failed (exit status $CHECK_STATUS)" >&2 | |
| exit "$CHECK_STATUS" | |
| fi | |
| - name: Quick change detection and early exit | |
| id: quick_check | |
| run: | | |
| echo "π Quick check for changes to determine if we should continue..." | |
| # The unreleased changelog is the release input. Do not infer that a | |
| # release is needed from arbitrary commits after the previous tag: | |
| # release bookkeeping, documentation automation, and other unrelated | |
| # commits must not create a release by themselves. | |
| if [ "${{ steps.changelog_check.outputs.has_unreleased_content }}" == "true" ]; then | |
| echo "β Found unreleased changelog content, proceeding with release" | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| echo "should_continue=true" >> $GITHUB_OUTPUT | |
| echo "reason=Found unreleased changelog content" >> $GITHUB_OUTPUT | |
| else | |
| echo "βΉοΈ No unreleased changelog content found; skipping release." | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| echo "should_continue=false" >> $GITHUB_OUTPUT | |
| echo "reason=No unreleased changelog content" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Early exit - No changes detected | |
| if: | | |
| steps.quick_check.outputs.should_continue == 'false' && | |
| github.event.inputs.force_release != 'true' && | |
| inputs.release_version == '' | |
| run: | | |
| echo "π EARLY EXIT: ${{ steps.quick_check.outputs.reason }}" | |
| echo "" | |
| echo "βΉοΈ No changes detected since last release and force_release is not enabled." | |
| echo " Workflow will exit early to save resources." | |
| echo "" | |
| echo " To force a release anyway, run this workflow with 'force_release=true'" | |
| echo "" | |
| echo "## π Early Exit Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "**Reason:** ${{ steps.quick_check.outputs.reason }}" >> $GITHUB_STEP_SUMMARY | |
| echo "**Action:** Workflow exited early to save resources" >> $GITHUB_STEP_SUMMARY | |
| echo "**Force Release:** Set 'force_release=true' to override this behavior" >> $GITHUB_STEP_SUMMARY | |
| exit 0 | |
| - name: Continue with release process | |
| if: | | |
| steps.quick_check.outputs.should_continue == 'true' || | |
| github.event.inputs.force_release == 'true' || | |
| inputs.release_version != '' | |
| run: | | |
| echo "β Proceeding with release process..." | |
| if [ "${{ github.event.inputs.force_release }}" == "true" ]; then | |
| echo "π¨ FORCE RELEASE: Overriding change detection" | |
| fi | |
| - name: Verify changelog workflow evidence | |
| if: | | |
| steps.quick_check.outputs.should_continue == 'true' || | |
| github.event.inputs.force_release == 'true' || | |
| inputs.release_version != '' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| python3 -m unittest discover -s v3/scripts -p 'test_check_changelog_runs.py' | |
| python3 v3/scripts/check-changelog-runs.py | |
| - name: Run release script | |
| id: release | |
| if: | | |
| steps.quick_check.outputs.should_continue == 'true' || | |
| github.event.inputs.force_release == 'true' || | |
| inputs.release_version != '' | |
| env: | |
| # Keep these DISTINCT: the release script validates WAILS_REPO_TOKEN | |
| # against the API before pushing anything and falls back to | |
| # GITHUB_TOKEN if the PAT is expired/revoked. Passing the same value | |
| # for both (as before) made the fallback meaningless and an expired | |
| # PAT produced a half-release: tag pushed, no GitHub release. | |
| WAILS_REPO_TOKEN: ${{ secrets.WAILS_REPO_TOKEN }} | |
| GITHUB_TOKEN: ${{ github.token }} | |
| DRY_RUN: ${{ inputs.dry_run }} | |
| RELEASE_VERSION: ${{ inputs.release_version }} | |
| run: | | |
| cd v3/tasks/release | |
| ARGS=() | |
| if [ "$DRY_RUN" == "true" ]; then | |
| ARGS+=(--dry-run) | |
| fi | |
| if [ -n "$RELEASE_VERSION" ]; then | |
| ARGS+=(--version "$RELEASE_VERSION") | |
| fi | |
| go run release.go "${ARGS[@]}" | |
| - name: Summary | |
| if: always() | |
| run: | | |
| if [ "${{ github.event.inputs.dry_run }}" == "true" ]; then | |
| echo "## π§ͺ DRY RUN Release Summary" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "## π Nightly Release Summary" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "================================" >> $GITHUB_STEP_SUMMARY | |
| if [ -n "${{ steps.release.outputs.release_version }}" ]; then | |
| echo "- **Version:** ${{ steps.release.outputs.release_version }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Tag:** ${{ steps.release.outputs.release_tag }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Status:** ${{ steps.release.outcome == 'success' && 'β Success' || 'β οΈ Failed' }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Mode:** ${{ steps.release.outputs.release_dry_run == 'true' && 'π§ͺ Dry Run' || 'π Live release' }}" >> $GITHUB_STEP_SUMMARY | |
| if [ -n "${{ steps.release.outputs.release_url }}" ]; then | |
| echo "- **Release URL:** ${{ steps.release.outputs.release_url }}" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Changelog" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ steps.changelog_check.outputs.has_unreleased_content }}" == "true" ]; then | |
| echo "β Unreleased changelog processed and reset." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "βΉοΈ No unreleased changelog content detected." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| else | |
| echo "- Release script did not run (skipped or failed before execution)." >> $GITHUB_STEP_SUMMARY | |
| fi | |