223 lines
12 KiB
YAML
223 lines
12 KiB
YAML
# Push a release to the lean4-pr-releases repository, whenever someone pushes to a PR branch.
|
|
|
|
# This needs to run with the `secrets.PR_RELEASES_TOKEN` token available,
|
|
# but PR branches will generally come from forks,
|
|
# so it is not possible to run this using the `pull_request` or `pull_request_target` workflows.
|
|
# Instead we use `workflow_run`, which essentially allows us to escalate privileges
|
|
# (but only runs the CI as described in the `master` branch, not in the PR branch).
|
|
|
|
name: PR release
|
|
|
|
on:
|
|
workflow_run: # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run
|
|
workflows: [CI]
|
|
types: [completed]
|
|
|
|
jobs:
|
|
on-success:
|
|
runs-on: ubuntu-latest
|
|
if: github.event.workflow_run.conclusion == 'success' && github.repository == 'leanprover/lean4'
|
|
steps:
|
|
- name: Retrieve information about the original workflow
|
|
uses: potiuk/get-workflow-origin@v1_1 # https://github.com/marketplace/actions/get-workflow-origin
|
|
id: workflow-info
|
|
with:
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
sourceRunId: ${{ github.event.workflow_run.id }}
|
|
- name: Checkout
|
|
# Only proceed if the previous workflow had a pull request number.
|
|
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
|
|
uses: actions/checkout@v3
|
|
with:
|
|
token: ${{ secrets.PR_RELEASES_TOKEN }}
|
|
# Since `workflow_run` runs on master, we need to specify which commit to check out,
|
|
# so that we tag the PR.
|
|
ref: ${{ steps.workflow-info.outputs.targetCommitSha }}
|
|
# We need a full checkout, so that we can push the PR commits to the `lean4-pr-releases` repo.
|
|
fetch-depth: 0
|
|
|
|
- name: Download artifact from the previous workflow.
|
|
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
|
|
id: download-artifact
|
|
uses: dawidd6/action-download-artifact@v2 # https://github.com/marketplace/actions/download-workflow-artifact
|
|
with:
|
|
run_id: ${{ github.event.workflow_run.id }}
|
|
path: artifacts
|
|
name: build-.*
|
|
name_is_regexp: true
|
|
- name: Prepare release
|
|
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
|
|
run: |
|
|
git remote add pr-releases https://foo:'${{ secrets.PR_RELEASES_TOKEN }}'@github.com/${{ github.repository_owner }}/lean4-pr-releases.git
|
|
# Try to delete any existing release for the current PR.
|
|
gh release delete --repo ${{ github.repository_owner }}/lean4-pr-releases pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }} -y || true
|
|
git tag -f pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}
|
|
git push -f pr-releases pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}
|
|
env:
|
|
GH_TOKEN: ${{ secrets.PR_RELEASES_TOKEN }}
|
|
- name: Release
|
|
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
|
|
uses: softprops/action-gh-release@v1
|
|
with:
|
|
name: Release for PR ${{ steps.workflow-info.outputs.pullRequestNumber }}
|
|
# There are coredumps files here as well, but all in deeper subdirectories.
|
|
files: artifacts/*/*
|
|
fail_on_unmatched_files: true
|
|
draft: false
|
|
tag_name: pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}
|
|
repository: ${{ github.repository_owner }}/lean4-pr-releases
|
|
env:
|
|
# The token used here must have `workflow` privileges.
|
|
GITHUB_TOKEN: ${{ secrets.PR_RELEASES_TOKEN }}
|
|
|
|
- name: Add label
|
|
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
|
|
uses: actions-ecosystem/action-add-labels@v1
|
|
with:
|
|
number: ${{ steps.workflow-info.outputs.pullRequestNumber }}
|
|
labels: toolchain-available
|
|
|
|
# Next, determine the most recent nightly release in this PR's history.
|
|
- name: Find most recent nightly
|
|
id: most-recent-nightly-tag
|
|
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
|
|
run: |
|
|
git remote add nightly https://foo:'${{ secrets.PUSH_NIGHTLY_TOKEN }}'@github.com/${{ github.repository_owner }}/lean4-nightly.git
|
|
echo "MOST_RECENT_NIGHTLY=$(script/most-recent-nightly-tag.sh)" >> $GITHUB_ENV
|
|
|
|
- name: 'Setup jq'
|
|
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
|
|
uses: dcarbone/install-jq-action@v1.0.1
|
|
|
|
# Check that the most recently nightly coincides with 'git merge-base HEAD master'
|
|
- name: Check merge-base and nightly-testing-YYYY-MM-DD
|
|
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }}
|
|
id: ready
|
|
run: |
|
|
echo "Most recent nightly: $MOST_RECENT_NIGHTLY"
|
|
NIGHTLY_SHA=$(git rev-parse nightly-$MOST_RECENT_NIGHTLY^{commit})
|
|
echo "SHA of most recent nightly: $NIGHTLY_SHA"
|
|
MERGE_BASE_SHA=$(git merge-base origin/master HEAD)
|
|
echo "SHA of merge-base: $MERGE_BASE_SHA"
|
|
if [ "$NIGHTLY_SHA" = "$MERGE_BASE_SHA" ]; then
|
|
echo "Most recent nightly tag agrees with the merge base."
|
|
|
|
REMOTE_BRANCHES=$(git ls-remote -h https://github.com/leanprover-community/mathlib4.git nightly-testing-$MOST_RECENT_NIGHTLY)
|
|
|
|
if [[ -n "$REMOTE_BRANCHES" ]]; then
|
|
echo "... and Mathlib has a 'nightly-testing-$MOST_RECENT_NIGHTLY' branch."
|
|
MESSAGE=""
|
|
else
|
|
echo "... but Mathlib does not yet have a 'nightly-testing-$MOST_RECENT_NIGHTLY' branch."
|
|
MESSAGE="- ❗ Mathlib CI can not be attempted yet, as the 'nightly-testing-$MOST_RECENT_NIGHTLY' branch does not exist there yet. We will retry when you push more commits. It may be necessary to rebase onto 'nightly' tomorrow."
|
|
fi
|
|
|
|
else
|
|
echo "The most recently nightly tag on this branch has SHA: $NIGHTLY_SHA"
|
|
echo "but 'git merge-base origin/master HEAD' reported: $MERGE_BASE_SHA"
|
|
|
|
MESSAGE="- ❗ Mathlib CI will not be attempted unless you rebase your PR onto the 'nightly' branch."
|
|
fi
|
|
|
|
if [[ -n "$MESSAGE" ]]; then
|
|
|
|
echo "Checking existing messages"
|
|
|
|
# Use GitHub API to check if a comment already exists
|
|
existing_comment=$(curl -L -s -H "Authorization: token ${{ secrets.MATHLIB4_BOT }}" \
|
|
-H "Accept: application/vnd.github.v3+json" \
|
|
"https://api.github.com/repos/leanprover/lean4/issues/${{ steps.workflow-info.outputs.pullRequestNumber }}/comments" \
|
|
| jq '.[] | select(.body | startswith("- ❗ Mathlib") or startswith("- ✅ Mathlib") or startswith("- ❌ Mathlib") or startswith("- 💥 Mathlib") or startswith("- 🟡 Mathlib"))')
|
|
existing_comment_id=$(echo "$existing_comment" | jq -r .id)
|
|
existing_comment_body=$(echo "$existing_comment" | jq -r .body)
|
|
|
|
if [[ "$existing_comment_body" != *"$MESSAGE"* ]]; then
|
|
MESSAGE="$MESSAGE ($(date "+%Y-%m-%d %H:%M:%S"))"
|
|
|
|
echo "Posting message to the comments: $MESSAGE"
|
|
|
|
# Append new result to the existing comment or post a new comment
|
|
# It's essential we use the MATHLIB4_BOT token here, so that Mathlib CI can subsequently edit the comment.
|
|
if [ -z "$existing_comment_id" ]; then
|
|
# Post new comment with a bullet point
|
|
echo "Posting as new comment at leanprover/lean4/issues/${{ steps.workflow-info.outputs.pullRequestNumber }}/comments"
|
|
curl -L -s \
|
|
-X POST \
|
|
-H "Authorization: token ${{ secrets.MATHLIB4_BOT }}" \
|
|
-H "Accept: application/vnd.github.v3+json" \
|
|
-d "$(jq --null-input --arg val "$MESSAGE" '{"body": $val}')" \
|
|
"https://api.github.com/repos/leanprover/lean4/issues/${{ steps.workflow-info.outputs.pullRequestNumber }}/comments"
|
|
else
|
|
# Append new result to the existing comment
|
|
echo "Appending to existing comment at leanprover/lean4/issues/${{ steps.workflow-info.outputs.pullRequestNumber }}/comments"
|
|
curl -L -s \
|
|
-X PATCH \
|
|
-H "Authorization: token ${{ secrets.MATHLIB4_BOT }}" \
|
|
-H "Accept: application/vnd.github.v3+json" \
|
|
-d "$(jq --null-input --arg existing "$existing_comment_body" --arg message "$MESSAGE" '{"body":($existing + "\n" + $message)}')" \
|
|
"https://api.github.com/repos/leanprover/lean4/issues/comments/$existing_comment_id"
|
|
fi
|
|
else
|
|
echo "The message already exists in the comment body."
|
|
fi
|
|
echo "::set-output name=mathlib_ready::false"
|
|
else
|
|
echo "::set-output name=mathlib_ready::true"
|
|
fi
|
|
|
|
# We next automatically create a Mathlib branch using this toolchain.
|
|
# Mathlib CI will be responsible for reporting back success or failure
|
|
# to the PR comments asynchronously.
|
|
- name: Cleanup workspace
|
|
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }} && ${{ steps.ready.outputs.mathlib_ready == 'true' }}
|
|
run: |
|
|
sudo rm -rf *
|
|
|
|
# Checkout the mathlib4 repository with all branches
|
|
- name: Checkout mathlib4 repository
|
|
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }} && ${{ steps.ready.outputs.mathlib_ready == 'true' }}
|
|
uses: actions/checkout@v3
|
|
with:
|
|
repository: leanprover-community/mathlib4
|
|
token: ${{ secrets.MATHLIB4_BOT }}
|
|
ref: nightly-testing
|
|
fetch-depth: 0 # This ensures we check out all tags and branches.
|
|
|
|
- name: Check if branch exists
|
|
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }} && ${{ steps.ready.outputs.mathlib_ready == 'true' }}
|
|
id: check_branch
|
|
run: |
|
|
git config user.name "leanprover-community-mathlib4-bot"
|
|
git config user.email "leanprover-community-mathlib4-bot@users.noreply.github.com"
|
|
|
|
if git branch -r | grep -q "nightly-testing-${MOST_RECENT_NIGHTLY}"; then
|
|
BASE=nightly-testing-${MOST_RECENT_NIGHTLY}
|
|
else
|
|
echo "This shouldn't be possible: couldn't find a 'nightly-testing-${MOST_RECENT_NIGHTLY}' branch at Mathlib. Falling back to 'nightly-testing'."
|
|
BASE=nightly-testing
|
|
fi
|
|
|
|
echo "Using base branch: $BASE"
|
|
|
|
git checkout $BASE
|
|
|
|
EXISTS=$(git ls-remote --heads origin lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }} | wc -l)
|
|
echo "Branch exists: $EXISTS"
|
|
if [ "$EXISTS" = "0" ]; then
|
|
echo "Branch does not exist, creating it."
|
|
git checkout -b lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }}
|
|
echo "leanprover/lean4-pr-releases:pr-release-${{ steps.workflow-info.outputs.pullRequestNumber }}" > lean-toolchain
|
|
git add lean-toolchain
|
|
git commit -m "Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
|
|
else
|
|
echo "Branch already exists, pushing an empty commit."
|
|
git checkout lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }}
|
|
# The Mathlib `nightly-testing` or `nightly-testing-YYYY-MM-DD` branch may have moved since this branch was created, so merge their changes.
|
|
git merge $BASE --strategy-option ours --no-commit --allow-unrelated-histories
|
|
git commit --allow-empty -m "Trigger CI for https://github.com/leanprover/lean4/pull/${{ steps.workflow-info.outputs.pullRequestNumber }}"
|
|
fi
|
|
|
|
- name: Push changes
|
|
if: ${{ steps.workflow-info.outputs.pullRequestNumber != '' }} && ${{ steps.ready.outputs.mathlib_ready == 'true' }}
|
|
run: |
|
|
git push origin lean-pr-testing-${{ steps.workflow-info.outputs.pullRequestNumber }}
|