Check Upstream and Rebase #2
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: Check Upstream and Rebase | |
| on: | |
| schedule: | |
| - cron: '0 */6 * * *' # 6時間ごと | |
| workflow_dispatch: | |
| jobs: | |
| check-and-rebase: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| new_tag: ${{ steps.check.outputs.new_tag }} | |
| current_tag: ${{ steps.check.outputs.current_tag }} | |
| should_build: ${{ steps.check.outputs.should_build }} | |
| rebase_success: ${{ steps.rebase.outputs.rebase_success }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GH_PAT }} | |
| - name: Check upstream for new tags | |
| id: check | |
| run: | | |
| UPSTREAM_REPO=mastodon/mastodon | |
| # 自リポジトリの最新タグを取得 | |
| CURRENT_TAG=$(git tag --sort=-v:refname | grep -E '^v?[0-9]+\.[0-9]+\.[0-9]+$' | head -1) | |
| echo "Current tag: $CURRENT_TAG" | |
| # バージョン番号をパース (v4.3.2 -> 4 3 2) | |
| CURRENT_CLEAN=${CURRENT_TAG#v} | |
| IFS='.' read -r CUR_MAJOR CUR_MINOR CUR_PATCH <<< "$CURRENT_CLEAN" | |
| # upstreamの最新タグ一覧を取得し、semver順にソート | |
| UPSTREAM_TAGS=$(gh api repos/$UPSTREAM_REPO/tags --paginate \ | |
| --jq '.[].name' \ | |
| | grep -E '^v?[0-9]+\.[0-9]+\.[0-9]+$' \ | |
| | sort -Vr \ | |
| | head -20) | |
| echo "Upstream tags (sorted):" | |
| echo "$UPSTREAM_TAGS" | |
| # 対象となるタグをフィルタ(現在より新しいもの) | |
| TARGET_TAG="" | |
| while IFS= read -r TAG; do | |
| CLEAN=${TAG#v} | |
| IFS='.' read -r UP_MAJOR UP_MINOR UP_PATCH <<< "$CLEAN" | |
| IS_NEWER=false | |
| if [ "$UP_MAJOR" -gt "$CUR_MAJOR" ]; then | |
| IS_NEWER=true | |
| elif [ "$UP_MAJOR" -eq "$CUR_MAJOR" ] && [ "$UP_MINOR" -gt "$CUR_MINOR" ]; then | |
| IS_NEWER=true | |
| elif [ "$UP_MAJOR" -eq "$CUR_MAJOR" ] && [ "$UP_MINOR" -eq "$CUR_MINOR" ] && [ "$UP_PATCH" -gt "$CUR_PATCH" ]; then | |
| IS_NEWER=true | |
| fi | |
| if [ "$IS_NEWER" = "true" ]; then | |
| TARGET_TAG=$TAG | |
| break # 最新1件のみ処理(複数あれば次回以降に処理) | |
| fi | |
| done <<< "$UPSTREAM_TAGS" | |
| if [ -z "$TARGET_TAG" ]; then | |
| echo "No new upstream tag found." | |
| echo "should_build=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "New upstream tag found: $TARGET_TAG" | |
| echo "new_tag=$TARGET_TAG" >> $GITHUB_OUTPUT | |
| echo "current_tag=$CURRENT_TAG" >> $GITHUB_OUTPUT | |
| echo "should_build=true" >> $GITHUB_OUTPUT | |
| fi | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Add upstream remote | |
| if: steps.check.outputs.should_build == 'true' | |
| run: | | |
| git remote add upstream https://github.com/mastodon/mastodon.git || true | |
| git fetch upstream --tags | |
| - name: Rebase onto upstream tag | |
| if: steps.check.outputs.should_build == 'true' | |
| id: rebase | |
| run: | | |
| NEW_TAG=${{ steps.check.outputs.new_tag }} | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| if git rebase upstream/$NEW_TAG; then | |
| echo "rebase_success=true" >> $GITHUB_OUTPUT | |
| echo "Rebase succeeded!" | |
| else | |
| echo "rebase_success=false" >> $GITHUB_OUTPUT | |
| git rebase --abort | |
| echo "Rebase failed!" | |
| fi | |
| - name: Push rebased branch | |
| if: steps.check.outputs.should_build == 'true' && steps.rebase.outputs.rebase_success == 'true' | |
| run: | | |
| git push origin HEAD --force-with-lease | |
| - name: Tag the new release | |
| if: steps.check.outputs.should_build == 'true' && steps.rebase.outputs.rebase_success == 'true' | |
| run: | | |
| NEW_TAG=${{ steps.check.outputs.new_tag }} | |
| git tag "$NEW_TAG" | |
| git push origin "$NEW_TAG" | |
| - name: Create issue on rebase failure | |
| if: steps.check.outputs.should_build == 'true' && steps.rebase.outputs.rebase_success == 'false' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const newTag = '${{ steps.check.outputs.new_tag }}'; | |
| const currentTag = '${{ steps.check.outputs.current_tag }}'; | |
| await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: `🚨 Rebase failed: upstream ${newTag}`, | |
| body: `## Rebase Conflict Detected\n\n` + | |
| `- **Current tag**: \`${currentTag}\`\n` + | |
| `- **Upstream tag**: \`${newTag}\`\n` + | |
| `- **Run**: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}\n\n` + | |
| `## 手順\n` + | |
| `\`\`\`bash\n` + | |
| `git fetch upstream\n` + | |
| `git rebase upstream/${newTag}\n` + | |
| `# conflict解消後\n` + | |
| `git push origin HEAD --force-with-lease\n` + | |
| `git tag ${newTag} && git push origin ${newTag}\n` + | |
| `\`\`\`\n\n` + | |
| `解消後は workflow_dispatch で build をトリガーしてください。`, | |
| labels: ['rebase-conflict', 'upstream-update'] | |
| }); | |
| build-and-push: | |
| needs: check-and-rebase | |
| # rebase_success が明示的に true の場合のみ実行 | |
| if: needs.check-and-rebase.outputs.should_build == 'true' && needs.check-and-rebase.outputs.rebase_success == 'true' | |
| uses: ./.github/workflows/build-container-image.yml | |
| with: | |
| file_to_build: Dockerfile | |
| push_to_images: ghcr.io/${{ github.repository }} | |
| cache: false | |
| flavor: | | |
| latest=true | |
| tags: | | |
| type=semver,pattern={{version}},value=${{ needs.check-and-rebase.outputs.new_tag }} | |
| type=semver,pattern={{major}}.{{minor}},value=${{ needs.check-and-rebase.outputs.new_tag }} | |
| secrets: inherit | |
| trigger-gitops: | |
| needs: | |
| - check-and-rebase | |
| - build-and-push | |
| if: needs.check-and-rebase.outputs.should_build == 'true' && needs.check-and-rebase.outputs.rebase_success == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Trigger GitOps update | |
| uses: peter-evans/repository-dispatch@v3 | |
| with: | |
| token: ${{ secrets.GH_PAT }} | |
| repository: highemerly/k8sg1-repo | |
| event-type: mastodon-image-updated | |
| client-payload: | | |
| { | |
| "image": "ghcr.io/${{ github.repository }}", | |
| "tag": "${{ needs.check-and-rebase.outputs.new_tag }}" | |
| } |