Merge upstream prometheus/prometheus branch #51
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: Merge upstream prometheus/prometheus branch | |
| on: | |
| schedule: | |
| - cron: "0 2 * * 1" # weekly at 2am on Monday | |
| workflow_dispatch: | |
| inputs: | |
| upstream_branch: | |
| description: "Upstream branch to merge from prometheus/prometheus" | |
| required: true | |
| default: "main" | |
| type: string | |
| local_branch: | |
| description: "Local branch to merge into" | |
| required: true | |
| default: "main" | |
| type: string | |
| jobs: | |
| check-merge: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| outputs: | |
| merge_needed: ${{ steps.check-merge.outputs.merge_needed }} | |
| upstream_branch: ${{ steps.set-branches.outputs.upstream_branch }} | |
| local_branch: ${{ steps.set-branches.outputs.local_branch }} | |
| timestamp: ${{ steps.set-branches.outputs.timestamp }} | |
| upstream_commit: ${{ steps.get-upstream-info.outputs.upstream_commit }} | |
| upstream_short: ${{ steps.get-upstream-info.outputs.upstream_short }} | |
| commit_date: ${{ steps.get-upstream-info.outputs.commit_date }} | |
| bot_branch: ${{ steps.set-branches.outputs.bot_branch }} | |
| steps: | |
| - name: Set default branches for scheduled runs | |
| id: set-branches | |
| env: | |
| UPSTREAM_BRANCH: ${{ inputs.upstream_branch || 'main' }} | |
| LOCAL_BRANCH: ${{ inputs.local_branch || 'main' }} | |
| run: | | |
| # Create timestamp for branch naming | |
| TIMESTAMP=$(date +%Y%m%d%H%M) | |
| # Compute bot branch name pattern | |
| BOT_BRANCH="bot/$LOCAL_BRANCH/merge-upstream-$UPSTREAM_BRANCH-$TIMESTAMP" | |
| echo "upstream_branch=$UPSTREAM_BRANCH" >> $GITHUB_OUTPUT | |
| echo "local_branch=$LOCAL_BRANCH" >> $GITHUB_OUTPUT | |
| echo "timestamp=$TIMESTAMP" >> $GITHUB_OUTPUT | |
| echo "bot_branch=$BOT_BRANCH" >> $GITHUB_OUTPUT | |
| echo "Upstream branch: $UPSTREAM_BRANCH" | |
| echo "Local branch: $LOCAL_BRANCH" | |
| echo "Bot branch: $BOT_BRANCH" | |
| - name: Check out repository | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ steps.set-branches.outputs.local_branch }} | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| fetch-depth: 0 | |
| set-safe-directory: "*" | |
| - name: Add prometheus/prometheus remote and fetch | |
| env: | |
| UPSTREAM_BRANCH: ${{ steps.set-branches.outputs.upstream_branch }} | |
| run: | | |
| echo "Adding prometheus/prometheus as remote..." | |
| git remote add prometheus https://github.com/prometheus/prometheus.git | |
| # Fetch the upstream branch | |
| echo "Fetching branch $UPSTREAM_BRANCH from prometheus/prometheus..." | |
| git fetch prometheus $UPSTREAM_BRANCH | |
| # Verify the branch exists | |
| if ! git show-ref --verify --quiet refs/remotes/prometheus/$UPSTREAM_BRANCH; then | |
| echo "Error: Branch $UPSTREAM_BRANCH not found in prometheus/prometheus" | |
| exit 1 | |
| fi | |
| echo "Successfully fetched upstream branch $UPSTREAM_BRANCH" | |
| - name: Get upstream commit info | |
| id: get-upstream-info | |
| env: | |
| UPSTREAM_BRANCH: ${{ steps.set-branches.outputs.upstream_branch }} | |
| run: | | |
| # Get latest commit info from upstream branch | |
| UPSTREAM_COMMIT=$(git rev-parse prometheus/$UPSTREAM_BRANCH) | |
| UPSTREAM_SHORT=$(echo "$UPSTREAM_COMMIT" | cut -c1-12) | |
| COMMIT_DATE=$(git log --format="%ad" --date=short -n 1 prometheus/$UPSTREAM_BRANCH) | |
| echo "upstream_commit=$UPSTREAM_COMMIT" >> $GITHUB_OUTPUT | |
| echo "upstream_short=$UPSTREAM_SHORT" >> $GITHUB_OUTPUT | |
| echo "commit_date=$COMMIT_DATE" >> $GITHUB_OUTPUT | |
| echo "Upstream commit: $UPSTREAM_COMMIT" | |
| - name: Check if merge is needed | |
| id: check-merge | |
| env: | |
| UPSTREAM_BRANCH: ${{ steps.set-branches.outputs.upstream_branch }} | |
| LOCAL_BRANCH: ${{ steps.set-branches.outputs.local_branch }} | |
| run: | | |
| # Check if upstream has new commits | |
| UPSTREAM_COMMIT=$(git rev-parse prometheus/$UPSTREAM_BRANCH) | |
| # Check if we already have this commit | |
| if git merge-base --is-ancestor $UPSTREAM_COMMIT HEAD; then | |
| echo "merge_needed=false" >> $GITHUB_OUTPUT | |
| echo "No new commits to merge from upstream $UPSTREAM_BRANCH" | |
| else | |
| echo "merge_needed=true" >> $GITHUB_OUTPUT | |
| echo "New commits found in upstream $UPSTREAM_BRANCH" | |
| # Show what would be merged | |
| echo "Commits to be merged:" | |
| git log --oneline HEAD..prometheus/$UPSTREAM_BRANCH | head -10 | |
| fi | |
| attempt-merge: | |
| runs-on: ubuntu-latest | |
| needs: check-merge | |
| if: needs.check-merge.outputs.merge_needed == 'true' | |
| permissions: | |
| contents: read | |
| outputs: | |
| merge_result: ${{ steps.merge-attempt.outputs.merge_result }} | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ needs.check-merge.outputs.local_branch }} | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| fetch-depth: 0 | |
| set-safe-directory: "*" | |
| - name: Add prometheus/prometheus remote and fetch | |
| run: | | |
| git remote add prometheus https://github.com/prometheus/prometheus.git | |
| git fetch prometheus ${{ needs.check-merge.outputs.upstream_commit }} | |
| - name: Attempt merge | |
| id: merge-attempt | |
| run: | | |
| # Configure git for the merge | |
| git config user.name "mimir-github-bot[bot]" | |
| git config user.email "mimir-github-bot[bot]@users.noreply.github.com" | |
| echo "Attempting to merge ${{ needs.check-merge.outputs.upstream_commit }}..." | |
| # Attempt the merge | |
| if git merge ${{ needs.check-merge.outputs.upstream_commit }} --no-edit; then | |
| echo "merge_result=success" >> $GITHUB_OUTPUT | |
| echo "Merge successful!" | |
| git log --oneline -1 | |
| else | |
| # Reset to clean state | |
| git merge --abort | |
| # Check if conflicts exist | |
| git merge ${{ needs.check-merge.outputs.upstream_commit }} --no-commit --no-ff || true | |
| if git diff --name-only --diff-filter=U | grep -q .; then | |
| echo "merge_result=conflicts" >> $GITHUB_OUTPUT | |
| echo "Merge conflicts detected in:" | |
| git diff --name-only --diff-filter=U | |
| else | |
| echo "merge_result=error" >> $GITHUB_OUTPUT | |
| echo "Merge failed for unknown reasons" | |
| fi | |
| git reset --hard HEAD | |
| fi | |
| handle-conflicts: | |
| runs-on: ubuntu-latest | |
| needs: [check-merge, attempt-merge] | |
| if: needs.attempt-merge.outputs.merge_result == 'conflicts' | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| id-token: write | |
| outputs: | |
| pr_url: ${{ steps.create-conflict-pr.outputs.pull-request-url }} | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ needs.check-merge.outputs.local_branch }} | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| fetch-depth: 0 | |
| set-safe-directory: "*" | |
| - name: Create empty commit for PR | |
| run: | | |
| # Configure git | |
| git config user.name "mimir-github-bot[bot]" | |
| git config user.email "mimir-github-bot[bot]@users.noreply.github.com" | |
| # Create an empty commit to establish the branch | |
| git commit --allow-empty -m "Empty commit to create branch for conflict resolution" | |
| # This job uses "mimir-github-bot" instead of "github-actions bot" (secrets.GITHUB_TOKEN) | |
| # because any events triggered by the later don't spawn GitHub actions. | |
| # Refer to https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow | |
| - name: Retrieve GitHub App Credentials from Vault | |
| id: get-secrets | |
| uses: grafana/shared-workflows/actions/get-vault-secrets@28361cdb22223e5f1e34358c86c20908e7248760 # v1.1.0 | |
| with: | |
| repo_secrets: | | |
| APP_ID=mimir-github-bot:app_id | |
| PRIVATE_KEY=mimir-github-bot:private_key | |
| - name: Generate GitHub App Token | |
| id: app-token | |
| uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1.12.0 | |
| with: | |
| app-id: ${{ env.APP_ID }} | |
| private-key: ${{ env.PRIVATE_KEY }} | |
| owner: ${{ github.repository_owner }} | |
| - name: Create empty PR for conflict resolution | |
| id: create-conflict-pr | |
| uses: peter-evans/create-pull-request@4e1beaa7521e8b457b572c090b25bd3db56bf1c5 # v5.0.3 | |
| with: | |
| token: ${{ steps.app-token.outputs.token }} | |
| title: "[${{ needs.check-merge.outputs.local_branch }}] Merge upstream prometheus/${{ needs.check-merge.outputs.upstream_branch }} to ${{ needs.check-merge.outputs.upstream_short }}" | |
| body: | | |
| ## Merge Conflicts Detected | |
| *This PR was automatically created by the [merge-upstream-prometheus workflow](https://github.com/grafana/mimir-prometheus/blob/main/.github/workflows/merge-upstream-prometheus.yml) due to merge conflicts.* | |
| **For reviewers**: After conflicts are resolved, the author should post a comment with the output of `git show --remerge-diff`. This shows how merge conflicts were manually resolved compared to what Git would have done automatically, making conflict resolution transparent and allowing validation that conflicts were resolved correctly. | |
| ### Details | |
| - **Upstream branch**: `${{ needs.check-merge.outputs.upstream_branch }}` | |
| - **Local branch**: `${{ needs.check-merge.outputs.local_branch }}` | |
| - **Latest upstream commit**: ${{ format('[`{0}`](https://github.com/prometheus/prometheus/commit/{0})', needs.check-merge.outputs.upstream_commit) }} | |
| - **Latest upstream commit date**: ${{ needs.check-merge.outputs.commit_date }} | |
| ### Action Required | |
| This **closed PR** serves as a placeholder that holds the branch and instructions for conflict resolution. Follow these steps to resolve conflicts and reopen this PR: | |
| ```bash | |
| # 1. Fetch and check out the empty branch created by CI | |
| git fetch origin | |
| git checkout ${{ needs.check-merge.outputs.bot_branch }} | |
| # 2. Fetch and merge the upstream commit to trigger conflicts | |
| git remote add upstream https://github.com/prometheus/prometheus.git # Omit this step if you already have a remote configured for prometheus/prometheus. | |
| git fetch upstream | |
| git merge ${{ needs.check-merge.outputs.upstream_commit }} --no-edit | |
| # 3. If conflicts occur: | |
| # - Edit conflicted files and resolve conflicts | |
| # - Look for conflict markers: <<<<<<< HEAD, =======, >>>>>>> | |
| # - Remove conflict markers after resolving | |
| # - Run: git add . && git merge --continue | |
| # 4. Push your resolved merge (no force-push needed) | |
| git push | |
| # 5. Re-open the closed PR | |
| # 6. Post the remerge diff as a comment for reviewers: | |
| gh pr comment --body "## Merge Conflict Resolution | |
| You can review how conflicts were resolved using: | |
| \`\`\`bash | |
| git show --remerge-diff | |
| \`\`\` | |
| <details> | |
| <summary>Click to expand remerge diff output</summary> | |
| \`\`\`diff | |
| $(git show --remerge-diff) | |
| \`\`\` | |
| </details>" | |
| ``` | |
| commit-message: "Empty commit to create branch for conflict resolution" | |
| branch: ${{ needs.check-merge.outputs.bot_branch }} | |
| base: ${{ needs.check-merge.outputs.local_branch }} | |
| delete-branch: false | |
| draft: true | |
| - name: Close PR by force-pushing to HEAD~1 | |
| run: | | |
| # Force-push to the same commit as the base branch (removes the empty commit, leaving no commits in the PR). | |
| # This closes the PR while keeping the branch and instructions as a placeholder | |
| git push --force origin ${{needs.check-merge.outputs.local_branch}}:${{ needs.check-merge.outputs.bot_branch }} | |
| - name: Send Slack notification for merge conflicts | |
| uses: grafana/shared-workflows/actions/send-slack-message@7b628e7352c2dea057c565cc4fcd5564d5f396c0 #v1.0.0 | |
| with: | |
| channel-id: C04AF91LPFX #mimir-ci-notifications | |
| payload: | | |
| { | |
| "text": ":sadcomputer: *Merge conflicts detected in upstream prometheus merge* (prometheus/`${{ needs.check-merge.outputs.upstream_branch }}` -> mimir-prometheus/`${{ needs.check-merge.outputs.local_branch }}`)\n\n<!subteam^S05TQM9UAAF> check and resolve the conflicts in <${{ steps.create-conflict-pr.outputs.pull-request-url }}|the PR>." | |
| } | |
| handle-error: | |
| runs-on: ubuntu-latest | |
| needs: [check-merge, attempt-merge] | |
| if: needs.attempt-merge.outputs.merge_result == 'error' | |
| permissions: | |
| id-token: write | |
| steps: | |
| - name: Send Slack notification for merge error | |
| uses: grafana/shared-workflows/actions/send-slack-message@7b628e7352c2dea057c565cc4fcd5564d5f396c0 #v1.0.0 | |
| with: | |
| channel-id: C04AF91LPFX #mimir-ci-notifications | |
| payload: | | |
| { | |
| "text": ":sadcomputer: *Upstream prometheus merge failed* (prometheus/`${{ needs.check-merge.outputs.upstream_branch }}` -> mimir-prometheus/`${{ needs.check-merge.outputs.local_branch }}`)\n\n<!subteam^S05TQM9UAAF> please investigate the <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|workflow logs> and resolve manually." | |
| } | |
| - name: Mark workflow as failed | |
| run: exit 1 | |
| create-pr: | |
| runs-on: ubuntu-latest | |
| needs: [check-merge, attempt-merge] | |
| if: needs.attempt-merge.outputs.merge_result == 'success' | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| id-token: write | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ needs.check-merge.outputs.local_branch }} | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| fetch-depth: 0 | |
| set-safe-directory: "*" | |
| - name: Add prometheus/prometheus remote and perform merge | |
| run: | | |
| git remote add prometheus https://github.com/prometheus/prometheus.git | |
| git fetch prometheus ${{ needs.check-merge.outputs.upstream_commit }} | |
| # Configure git | |
| git config user.name "mimir-github-bot[bot]" | |
| git config user.email "mimir-github-bot[bot]@users.noreply.github.com" | |
| # Perform the merge (we know it will succeed) | |
| git merge ${{ needs.check-merge.outputs.upstream_commit }} --no-edit | |
| # This job uses "mimir-github-bot" instead of "github-actions bot" (secrets.GITHUB_TOKEN) | |
| # because any events triggered by the later don't spawn GitHub actions. | |
| # Refer to https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow | |
| - name: Retrieve GitHub App Credentials from Vault | |
| id: get-secrets | |
| uses: grafana/shared-workflows/actions/get-vault-secrets@28361cdb22223e5f1e34358c86c20908e7248760 # v1.1.0 | |
| with: | |
| repo_secrets: | | |
| APP_ID=mimir-github-bot:app_id | |
| PRIVATE_KEY=mimir-github-bot:private_key | |
| - name: Generate GitHub App Token | |
| id: app-token | |
| uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1.12.0 | |
| with: | |
| app-id: ${{ env.APP_ID }} | |
| private-key: ${{ env.PRIVATE_KEY }} | |
| owner: ${{ github.repository_owner }} | |
| - name: Create Pull Request | |
| id: create-pr | |
| uses: peter-evans/create-pull-request@4e1beaa7521e8b457b572c090b25bd3db56bf1c5 # v5.0.3 | |
| with: | |
| token: ${{ steps.app-token.outputs.token }} | |
| title: "[${{ needs.check-merge.outputs.local_branch }}] Merge upstream prometheus/${{ needs.check-merge.outputs.upstream_branch }} to ${{ needs.check-merge.outputs.upstream_short }}" | |
| body: | | |
| ## Merge from prometheus/prometheus | |
| *This PR was automatically created by the [merge-upstream-prometheus workflow](https://github.com/grafana/mimir-prometheus/blob/main/.github/workflows/merge-upstream-prometheus.yml)* | |
| ### Details: | |
| - **Upstream branch**: `${{ needs.check-merge.outputs.upstream_branch }}` | |
| - **Local branch**: `${{ needs.check-merge.outputs.local_branch }}` | |
| - **Latest upstream commit**: ${{ format('[`{0}`](https://github.com/prometheus/prometheus/commit/{0})', needs.check-merge.outputs.upstream_commit) }} | |
| - **Latest upstream commit date**: ${{ needs.check-merge.outputs.commit_date }} | |
| ### Changes: | |
| This PR merges the latest changes from the upstream prometheus/prometheus `${{ needs.check-merge.outputs.upstream_branch }}` branch. | |
| commit-message: "Merge upstream prometheus/${{ needs.check-merge.outputs.upstream_branch }} (${{ needs.check-merge.outputs.upstream_short }})" | |
| branch: ${{ needs.check-merge.outputs.bot_branch }} | |
| base: ${{ needs.check-merge.outputs.local_branch }} | |
| delete-branch: true | |
| no-merge-needed: | |
| runs-on: ubuntu-latest | |
| needs: check-merge | |
| if: needs.check-merge.outputs.merge_needed == 'false' | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: No merge needed | |
| run: | | |
| echo "Repository is already up to date with upstream prometheus/${{ needs.check-merge.outputs.upstream_branch }}" |