Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 19 additions & 141 deletions .github/workflows/maintainer_bors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,10 @@ jobs:
COMMENT_REVIEW: ${{ github.event.review.body }}
PR_NUMBER: ${{ github.event.issue.number }}${{ github.event.pull_request.number }}
HAS_DELEGATED_LABEL: ${{ contains(github.event.issue.labels.*.name, 'delegated') }}
HAS_TRIAGE_SECRET: ${{ secrets.MATHLIB_TRIAGE_APP_ID != '' }}
name: Add ready-to-merge or delegated label
runs-on: ubuntu-latest
if: github.repository == 'leanprover-community/mathlib4'
steps:
- name: Generate app token
if: ${{ env.HAS_TRIAGE_SECRET == 'true' }}
id: app-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
with:
app-id: ${{ secrets.MATHLIB_TRIAGE_APP_ID }}
private-key: ${{ secrets.MATHLIB_TRIAGE_PRIVATE_KEY }}

- name: Find bors merge/delegate
id: merge_or_delegate
run: |
Expand Down Expand Up @@ -72,142 +63,29 @@ jobs:
then
printf $'bot=true\n'
printf $'bot=true\n' >> "${GITHUB_OUTPUT}"
BOT='true'
else
printf $'bot=false\n'
printf $'bot=false\n' >> "${GITHUB_OUTPUT}"
BOT='false'
fi

# write an artifact with all data needed below if we don't have access to necessary secrets
if [[ -z '${{ secrets.MATHLIB_TRIAGE_APP_ID }}' ]]
then
printf 'No access to secrets, writing to file.\n'
jq -n \
--arg author "${AUTHOR}" \
--arg pr_number "${PR_NUMBER}" \
--arg comment "${COMMENT}" \
--arg bot "${BOT}" \
--arg remove_labels "${remove_labels}" \
--arg m_or_d "${m_or_d}" \
'{
author: $author,
pr_number: $pr_number,
comment: $comment,
bot: $bot,
remove_labels: $remove_labels,
m_or_d: $m_or_d,
}' > artifact-data.json
echo "Generated JSON artifact:"
cat artifact-data.json

printf 'secrets=' >> "${GITHUB_OUTPUT}"
exit 0
else
printf 'secrets=true\n' >> "${GITHUB_OUTPUT}"
fi

# upload artifact if we have no access to secrets
- if: ${{ steps.merge_or_delegate.outputs.secrets == '' &&
(! steps.merge_or_delegate.outputs.mOrD == '' || ! steps.merge_or_delegate.outputs.removeLabels == '') }}
name: Upload artifact
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: workflow-data
path: artifact-data.json
retention-days: 5

# Run the following steps only if we have access to secrets / write perms on GITHUB_TOKEN
- name: Check whether user is a mathlib admin
id: user_permission
if: ${{ ! steps.merge_or_delegate.outputs.secrets == '' &&
(! steps.merge_or_delegate.outputs.mOrD == '' || ! steps.merge_or_delegate.outputs.removeLabels == '') }}
uses: actions-cool/check-user-permission@7b90a27f92f3961b368376107661682c441f6103 # v2.3.0
with:
require: 'admin'

- name: Add ready-to-merge or delegated label
id: add_label
if: ${{ ! steps.merge_or_delegate.outputs.secrets == '' &&
(! steps.merge_or_delegate.outputs.mOrD == '' &&
( steps.user_permission.outputs.require-result == 'true' ||
steps.merge_or_delegate.outputs.bot == 'true' )) }}
uses: octokit/request-action@dad4362715b7fb2ddedf9772c8670824af564f0d # v2.4.0
with:
route: POST /repos/:repository/issues/:issue_number/labels
# Unexpected input warning from the following is expected:
# https://github.com/octokit/request-action?tab=readme-ov-file#warnings
repository: ${{ github.repository }}
issue_number: ${{ github.event.issue.number }}${{ github.event.pull_request.number }}
labels: '["${{ steps.merge_or_delegate.outputs.mOrD }}"]'
env:
# The create-github-app-token README states that this token is masked and will not be logged accidentally.
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}

- if: ${{ ! steps.merge_or_delegate.outputs.secrets == '' &&
(! steps.merge_or_delegate.outputs.mOrD == '' &&
( steps.user_permission.outputs.require-result == 'true' ||
steps.merge_or_delegate.outputs.bot == 'true' )) }}
id: remove_labels
name: Remove "awaiting-author" and "maintainer-merge"
# we use curl rather than octokit/request-action so that the job won't fail
# (and send an annoying email) if the labels don't exist
run: |
for label in awaiting-author maintainer-merge; do
curl --request DELETE \
--url "https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}${{ github.event.pull_request.number }}/labels/${label}" \
--header 'authorization: Bearer ${{ steps.app-token.outputs.token }}'
done

- name: On bors r/d-, remove ready-to-merge or delegated label
if: ${{ ! steps.merge_or_delegate.outputs.secrets == '' &&
(! steps.merge_or_delegate.outputs.removeLabels == '' &&
steps.user_permission.outputs.require-result == 'true') }}
# we use curl rather than octokit/request-action so that the job won't fail
# (and send an annoying email) if the labels don't exist
- if: ${{ ! steps.merge_or_delegate.outputs.mOrD == '' || ! steps.merge_or_delegate.outputs.removeLabels == '' }}
name: Prepare bridge outputs
run: |
for label in ready-to-merge delegated; do
curl --request DELETE \
--url "https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}${{ github.event.pull_request.number }}/labels/${label}" \
--header 'authorization: Bearer ${{ steps.app-token.outputs.token }}'
done

- name: Set up Python
if: ${{ ! steps.merge_or_delegate.outputs.secrets == '' &&
(! steps.merge_or_delegate.outputs.mOrD == '' &&
( steps.user_permission.outputs.require-result == 'true' ||
steps.merge_or_delegate.outputs.bot == 'true' )) }}
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
jq -n \
--arg bot "${{ steps.merge_or_delegate.outputs.bot }}" \
--arg removeLabels "${{ steps.merge_or_delegate.outputs.removeLabels }}" \
--arg mOrD "${{ steps.merge_or_delegate.outputs.mOrD }}" \
'{
bot: $bot,
removeLabels: $removeLabels,
mOrD: $mOrD,
}' > bridge-outputs.json

- if: ${{ ! steps.merge_or_delegate.outputs.mOrD == '' || ! steps.merge_or_delegate.outputs.removeLabels == '' }}
name: Emit bridge artifact
uses: leanprover-community/privilege-escalation-bridge/emit@v1
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will change this uses (and the reference in the other file to /consume) to point to a specific commit after I'm more confident that the actions are stable.

with:
python-version: '3.x'

- name: Install dependencies
if: ${{ ! steps.merge_or_delegate.outputs.secrets == '' &&
(! steps.merge_or_delegate.outputs.mOrD == '' &&
( steps.user_permission.outputs.require-result == 'true' ||
steps.merge_or_delegate.outputs.bot == 'true' )) }}
run: |
python -m pip install --upgrade pip
pip install zulip

- if: ${{ ! steps.merge_or_delegate.outputs.secrets == '' &&
(! steps.merge_or_delegate.outputs.mOrD == '' &&
( steps.user_permission.outputs.require-result == 'true' ||
steps.merge_or_delegate.outputs.bot == 'true' )) }}
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: master
sparse-checkout: |
scripts/zulip_emoji_reactions.py

- name: update zulip emoji reactions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see where this has been moved to? Why is it that this used to be present in both workflows?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I need to add these back since they were used to add the :bors: and maintainer merge emoji reactions.

if: ${{ ! steps.merge_or_delegate.outputs.secrets == '' &&
(! steps.merge_or_delegate.outputs.mOrD == '' &&
( steps.user_permission.outputs.require-result == 'true' ||
steps.merge_or_delegate.outputs.bot == 'true' )) }}
env:
ZULIP_API_KEY: ${{ secrets.ZULIP_API_KEY }}
ZULIP_EMAIL: github-mathlib4-bot@leanprover.zulipchat.com
ZULIP_SITE: https://leanprover.zulipchat.com
run: |
python scripts/zulip_emoji_reactions.py "$ZULIP_API_KEY" "$ZULIP_EMAIL" "$ZULIP_SITE" "${{ steps.merge_or_delegate.outputs.mOrD }}" "${{ steps.merge_or_delegate.outputs.mOrD }}" "${{ github.event.issue.number }}${{ github.event.pull_request.number }}"
artifact: workflow-data
outputs_file: bridge-outputs.json
include_event: minimal
retention_days: 5
100 changes: 37 additions & 63 deletions .github/workflows/maintainer_bors_wf_run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ on:
types:
- completed

permissions:
actions: read
contents: read


jobs:
add_ready_to_merge_label:
Expand All @@ -20,133 +24,103 @@ jobs:
app-id: ${{ secrets.MATHLIB_TRIAGE_APP_ID }}
private-key: ${{ secrets.MATHLIB_TRIAGE_PRIVATE_KEY }}

- name: Download artifact
id: download-artifact
uses: dawidd6/action-download-artifact@5c98f0b039f36ef966fdb7dfa9779262785ecb05 # v14
- name: Consume bridge artifact
id: bridge
uses: leanprover-community/privilege-escalation-bridge/consume@v1
with:
workflow: maintainer_bors.yml
name: workflow-data
path: ./artifacts
if_no_artifact_found: ignore
# Use the workflow run that triggered this workflow
run_id: ${{ github.event.workflow_run.id }}

- if: ${{ steps.download-artifact.outputs.found_artifact == 'true' }}
name: Extract data from JSON artifact
id: extract-data
run: |
# Read the JSON artifact file and extract data
if [ -f "./artifacts/artifact-data.json" ]; then
echo "JSON artifact found, extracting data..."
echo "Full JSON artifact content:"
cat ./artifacts/artifact-data.json

# Extract specific values using jq
author=$(jq -r '.author' ./artifacts/artifact-data.json)
pr_number=$(jq -r '.pr_number' ./artifacts/artifact-data.json)
comment=$(jq -r '.comment' ./artifacts/artifact-data.json)
bot=$(jq -r '.bot' ./artifacts/artifact-data.json)
remove_labels=$(jq -r '.remove_labels' ./artifacts/artifact-data.json)
m_or_d=$(jq -r '.m_or_d' ./artifacts/artifact-data.json)

# Set as step outputs for use in later steps
{
echo "author=$author"
echo "pr_number=$pr_number"
echo "comment<<EOF"
echo "$comment"
echo "EOF"
echo "bot=$bot"
echo "removeLabels=$remove_labels"
echo "mOrD=$m_or_d"
} | tee -a "$GITHUB_OUTPUT"
else
echo "JSON artifact file not found!"
exit 1
fi
artifact: workflow-data
source_workflow: Add "ready-to-merge" and "delegated" label
require_event: issue_comment,pull_request_review,pull_request_review_comment
fail_on_missing: false
extract: |
author=event.comment.user.login|event.review.user.login
pr_number=meta.pr_number
bot=outputs.bot
removeLabels=outputs.removeLabels
mOrD=outputs.mOrD

- name: Check whether user is a mathlib admin
id: user_permission
if: ${{ ! steps.extract-data.outputs.mOrD == '' || ! steps.extract-data.outputs.removeLabels == '' }}
if: ${{ ! steps.bridge.outputs.mOrD == '' || ! steps.bridge.outputs.removeLabels == '' }}
uses: actions-cool/check-user-permission@7b90a27f92f3961b368376107661682c441f6103 # v2.3.0
with:
username: ${{ steps.extract-data.outputs.author }}
username: ${{ steps.bridge.outputs.author }}
require: 'admin'

- name: Add ready-to-merge or delegated label
id: add_label
if: ${{ ! steps.extract-data.outputs.mOrD == '' &&
if: ${{ ! steps.bridge.outputs.mOrD == '' &&
( steps.user_permission.outputs.require-result == 'true' ||
steps.extract-data.outputs.bot == 'true' ) }}
steps.bridge.outputs.bot == 'true' ) }}
uses: octokit/request-action@dad4362715b7fb2ddedf9772c8670824af564f0d # v2.4.0
with:
route: POST /repos/:repository/issues/:issue_number/labels
# Unexpected input warning from the following is expected:
# https://github.com/octokit/request-action?tab=readme-ov-file#warnings
repository: ${{ github.repository }}
issue_number: ${{ steps.extract-data.outputs.pr_number }}
labels: '["${{ steps.extract-data.outputs.mOrD }}"]'
issue_number: ${{ steps.bridge.outputs.pr_number }}
labels: '["${{ steps.bridge.outputs.mOrD }}"]'
env:
# The create-github-app-token README states that this token is masked and will not be logged accidentally.
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}

- if: ${{ ! steps.extract-data.outputs.mOrD == '' &&
- if: ${{ ! steps.bridge.outputs.mOrD == '' &&
( steps.user_permission.outputs.require-result == 'true' ||
steps.extract-data.outputs.bot == 'true' ) }}
steps.bridge.outputs.bot == 'true' ) }}
id: remove_labels
name: Remove "awaiting-author" and "maintainer-merge"
# we use curl rather than octokit/request-action so that the job won't fail
# (and send an annoying email) if the labels don't exist
run: |
for label in awaiting-author maintainer-merge; do
curl --request DELETE \
--url "https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.extract-data.outputs.pr_number }}/labels/${label}" \
--url "https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.bridge.outputs.pr_number }}/labels/${label}" \
--header 'authorization: Bearer ${{ steps.app-token.outputs.token }}'
done

- name: On bors r/d-, remove ready-to-merge or delegated label
if: ${{ ! steps.extract-data.outputs.removeLabels == '' && steps.user_permission.outputs.require-result == 'true' }}
if: ${{ ! steps.bridge.outputs.removeLabels == '' && steps.user_permission.outputs.require-result == 'true' }}
# we use curl rather than octokit/request-action so that the job won't fail
# (and send an annoying email) if the labels don't exist
run: |
for label in ready-to-merge delegated; do
curl --request DELETE \
--url "https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.extract-data.outputs.pr_number }}/labels/${label}" \
--url "https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.bridge.outputs.pr_number }}/labels/${label}" \
--header 'authorization: Bearer ${{ steps.app-token.outputs.token }}'
done

- name: Set up Python
if: ${{ ! steps.extract-data.outputs.mOrD == '' &&
if: ${{ ! steps.bridge.outputs.mOrD == '' &&
( steps.user_permission.outputs.require-result == 'true' ||
steps.extract-data.outputs.bot == 'true' ) }}
steps.bridge.outputs.bot == 'true' ) }}
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.x'

- name: Install dependencies
if: ${{ ! steps.extract-data.outputs.mOrD == '' &&
if: ${{ ! steps.bridge.outputs.mOrD == '' &&
( steps.user_permission.outputs.require-result == 'true' ||
steps.extract-data.outputs.bot == 'true' ) }}
steps.bridge.outputs.bot == 'true' ) }}
run: |
python -m pip install --upgrade pip
pip install zulip

- if: ${{ ! steps.extract-data.outputs.mOrD == '' &&
- if: ${{ ! steps.bridge.outputs.mOrD == '' &&
( steps.user_permission.outputs.require-result == 'true' ||
steps.extract-data.outputs.bot == 'true' ) }}
steps.bridge.outputs.bot == 'true' ) }}
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: master
sparse-checkout: |
scripts/zulip_emoji_reactions.py

- name: update zulip emoji reactions
if: ${{ ! steps.extract-data.outputs.mOrD == '' &&
if: ${{ ! steps.bridge.outputs.mOrD == '' &&
( steps.user_permission.outputs.require-result == 'true' ||
steps.extract-data.outputs.bot == 'true' ) }}
steps.bridge.outputs.bot == 'true' ) }}
env:
ZULIP_API_KEY: ${{ secrets.ZULIP_API_KEY }}
ZULIP_EMAIL: github-mathlib4-bot@leanprover.zulipchat.com
ZULIP_SITE: https://leanprover.zulipchat.com
run: |
python scripts/zulip_emoji_reactions.py "$ZULIP_API_KEY" "$ZULIP_EMAIL" "$ZULIP_SITE" "${{ steps.extract-data.outputs.mOrD }}" "${{ steps.extract-data.outputs.mOrD }}" "${{ steps.extract-data.outputs.pr_number }}"
python scripts/zulip_emoji_reactions.py "$ZULIP_API_KEY" "$ZULIP_EMAIL" "$ZULIP_SITE" "${{ steps.bridge.outputs.mOrD }}" "${{ steps.bridge.outputs.mOrD }}" "${{ steps.bridge.outputs.pr_number }}"
Loading