diff --git a/.github/workflows/auto-tag-rc.yml b/.github/workflows/auto-tag-rc.yml index 9c14641..f9408fd 100644 --- a/.github/workflows/auto-tag-rc.yml +++ b/.github/workflows/auto-tag-rc.yml @@ -12,6 +12,9 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + outputs: + tag: ${{ steps.tagger.outputs.TAG }} + rc_branch: ${{ steps.tagger.outputs.RC_BRANCH }} steps: - uses: actions/checkout@v4 with: @@ -21,7 +24,8 @@ jobs: id: tagger run: | # Use base ref (the target branch) since github.ref points to refs/pull/*/merge during PR events - VERSION=$(echo "${{ github.event.pull_request.base.ref }}" | sed -E 's#rc/##') + RC_BRANCH="${{ github.event.pull_request.base.ref }}" + VERSION=$(echo "$RC_BRANCH" | sed -E 's#rc/##') PREFIX="$VERSION-rc" echo "Looking for previous tags matching $PREFIX.*" @@ -32,6 +36,7 @@ jobs: TAG="$PREFIX.$NEXT" echo "TAG=$TAG" >> $GITHUB_OUTPUT + echo "RC_BRANCH=$RC_BRANCH" >> $GITHUB_OUTPUT - name: Create and push tag run: | @@ -39,3 +44,90 @@ jobs: git config user.email github-actions@users.noreply.github.com git tag ${{ steps.tagger.outputs.TAG }} git push origin ${{ steps.tagger.outputs.TAG }} + + sync-rc-to-dev: + needs: auto-tag-rc + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check if sync is needed + id: check-sync + run: | + RC_BRANCH="${{ needs.auto-tag-rc.outputs.rc_branch }}" + git fetch origin dev "$RC_BRANCH" + + # Check if there are commits in rc that aren't in dev + COMMITS_AHEAD=$(git rev-list --count origin/dev..origin/$RC_BRANCH) + + if [ "$COMMITS_AHEAD" -eq 0 ]; then + echo "No commits to sync from $RC_BRANCH to dev" + echo "needs_sync=false" >> $GITHUB_OUTPUT + else + echo "$COMMITS_AHEAD commits ahead - sync needed" + echo "needs_sync=true" >> $GITHUB_OUTPUT + fi + + - name: Create sync PR + if: steps.check-sync.outputs.needs_sync == 'true' + uses: actions/github-script@v7 + with: + script: | + const rcBranch = '${{ needs.auto-tag-rc.outputs.rc_branch }}'; + const tag = '${{ needs.auto-tag-rc.outputs.tag }}'; + + // Find and close any existing sync PRs for this RC branch (superseded by the new one) + const existingPRs = await github.rest.pulls.list({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + head: `${context.repo.owner}:${rcBranch}`, + base: 'dev' + }); + + for (const oldPR of existingPRs.data) { + console.log(`Closing superseded sync PR #${oldPR.number}`); + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: oldPR.number, + body: `Closing this PR as it has been superseded by a newer RC tag: \`${tag}\`.\n\nA new sync PR will be created with all the latest changes.` + }); + + await github.rest.pulls.update({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: oldPR.number, + state: 'closed' + }); + } + + // Create the new PR + const pr = await github.rest.pulls.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: `Sync ${rcBranch} to dev`, + body: `## Automated RC Sync + + This PR syncs changes from \`${rcBranch}\` back to \`dev\` to prevent branch deviation. + + **Triggered by:** ${tag} + + ### Review Notes + - Please review any hotfix changes that were applied directly to the RC branch + - Resolve any merge conflicts that may arise + - This helps ensure dev stays up-to-date with release fixes + + --- + *This PR was automatically created by the sync-rc-to-dev workflow.*`, + head: rcBranch, + base: 'dev' + }); + + console.log(`Created PR #${pr.data.number}: ${pr.data.html_url}`); diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 2e1bd70..791d75c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,4 +1,4 @@ -name: Zaino Release +name: Release on: push: @@ -8,8 +8,27 @@ on: workflow_dispatch: jobs: + # Check if Docker secrets are configured + check-docker-config: + name: Check Docker configuration + runs-on: ubuntu-latest + outputs: + docker_configured: ${{ steps.check.outputs.configured }} + steps: + - name: Check for Docker secrets + id: check + run: | + if [ -n "${{ secrets.DOCKERHUB_USERNAME }}" ] && [ -n "${{ secrets.DOCKERHUB_ACCESS_TOKEN }}" ]; then + echo "configured=true" >> $GITHUB_OUTPUT + else + echo "configured=false" >> $GITHUB_OUTPUT + echo "::notice::Docker secrets not configured - skipping Docker builds" + fi + docker: name: Docker images (build+push) + needs: check-docker-config + if: needs.check-docker-config.outputs.docker_configured == 'true' runs-on: ubuntu-latest env: PUSH_IMAGES: true @@ -75,7 +94,9 @@ jobs: type=gha,mode=max create-release: - needs: docker + needs: [check-docker-config, docker] + # Run even if docker was skipped (but not if it failed) + if: always() && (needs.docker.result == 'success' || needs.docker.result == 'skipped') name: Create GitHub Release runs-on: ubuntu-latest steps: diff --git a/README.md b/README.md index 8ad2dea..b2ee18f 100644 --- a/README.md +++ b/README.md @@ -1 +1,4 @@ # Release Flow Test Repo +hotfix for issue 1 +hotfix for issue 2 +hotfix for issue 3