Skip to content

Extend child process startup for duplication #6854

Extend child process startup for duplication

Extend child process startup for duplication #6854

Workflow file for this run

name: SemverChecks
# Run on pull requests or merge groups
on:
pull_request:
types:
- opened
- synchronize
- reopened
- edited
issue_comment:
types:
- created
- edited
- deleted
merge_group:
# If a new commit is pushed to the branch before ongoing runs finish, cancel the ongoing runs
concurrency:
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
cancel-in-progress: true
permissions:
contents: read
pull-requests: write
issues: write
env:
CARGO_TERM_COLOR: always
jobs:
rerun_fork_check:
name: Re-run fork semver check
if: >-
github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
(github.event.action == 'deleted' ||
contains(github.event.comment.body, ':robot: SemverChecks :robot:'))
permissions:
actions: write
contents: read
pull-requests: read
issues: read
runs-on: ubuntu-latest
steps:
- name: Re-run the pull request check
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
API_URL: ${{ github.api_url }}
REPOSITORY: ${{ github.repository }}
PR_NUMBER: ${{ github.event.issue.number }}
run: |
set -euo pipefail
PR=$(curl --fail-with-body -sS \
-H "Authorization: Bearer $GH_TOKEN" \
-H 'Accept: application/vnd.github+json' \
"$API_URL/repos/$REPOSITORY/pulls/$PR_NUMBER")
IS_OPEN=$(jq -r '.state == "open"' <<<"$PR")
IS_FORK=$(jq -r '.head.repo.fork == true' <<<"$PR")
COMMENTER_IS_AUTHOR=$(jq -r --arg login "${{ github.event.comment.user.login }}" '.user.login == $login' <<<"$PR")
COMMENTER_IS_MAINTAINER=$(case '${{ github.event.comment.author_association }}' in OWNER|MEMBER|COLLABORATOR) echo true;; *) echo false;; esac)
if [ "$IS_OPEN" != true ] || [ "$IS_FORK" != true ] || \
{ [ "$COMMENTER_IS_AUTHOR" != true ] && [ "$COMMENTER_IS_MAINTAINER" != true ]; }; then
echo 'Ignoring comment from an unauthorized user or on a non-open fork PR.'
exit 0
fi
HEAD_SHA=$(jq -r '.head.sha' <<<"$PR")
RUN_ID=$(curl --fail-with-body -sS \
-H "Authorization: Bearer $GH_TOKEN" \
-H 'Accept: application/vnd.github+json' \
"$API_URL/repos/$REPOSITORY/actions/workflows/semver-checks.yml/runs?event=pull_request&head_sha=$HEAD_SHA&per_page=10" | \
jq -r --argjson pr_number "$PR_NUMBER" '[.workflow_runs[] | select(any(.pull_requests[]?; .number == $pr_number))] | first | .id // empty')
if [ -z "$RUN_ID" ]; then
echo 'No pull_request semver-checks run exists for this commit yet.' >&2
exit 1
fi
curl --fail-with-body -sS -X POST \
-H "Authorization: Bearer $GH_TOKEN" \
-H 'Accept: application/vnd.github+json' \
"$API_URL/repos/$REPOSITORY/actions/runs/$RUN_ID/rerun"
semver_checks:
name: Check SemVer Correctness
if: ${{ github.event_name != 'issue_comment' }}
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Determine baseline ref
id: baseline
run: |
BASE_REF="${{ github.event.pull_request.base.ref }}"
MERGE_GROUP_BASE_REF="${{ github.event.merge_group.base_ref }}"
MERGE_GROUP_BASE_REF="${MERGE_GROUP_BASE_REF#refs/heads/}"
BASE_REF="${BASE_REF:-$MERGE_GROUP_BASE_REF}"
echo "ref=$BASE_REF" >> "$GITHUB_OUTPUT"
- name: Fetch baseline branch
run: git fetch origin "${{ steps.baseline.outputs.ref }}:${{ steps.baseline.outputs.ref }}"
- name: Set up Rust
run: |
rustup toolchain install $(awk -F'"' '/channel/{print $2}' rust-toolchain.toml) --profile minimal --no-self-update
- name: Determine packages to check
id: packages
run: |
git diff --name-only "${{ steps.baseline.outputs.ref }}" HEAD > /tmp/semver-checks-changed-files
python3 .github/tools/determine_semver_packages.py --changed-files /tmp/semver-checks-changed-files > /tmp/semver-checks-packages
if [ -s /tmp/semver-checks-packages ]; then
echo "has_packages=true" >> "$GITHUB_OUTPUT"
echo "Packages selected for semver checks:"
sed 's/^/ - /' /tmp/semver-checks-packages
else
echo "has_packages=false" >> "$GITHUB_OUTPUT"
echo "No semver-relevant crate changes detected."
fi
- name: Set up cargo-semver-checks
if: steps.packages.outputs.has_packages == 'true'
run: |
curl -L --proto '=https' --tlsv1.2 -sSf https://github.com/obi1kenobi/cargo-semver-checks/releases/latest/download/cargo-semver-checks-x86_64-unknown-linux-gnu.tar.gz | tar xzvf -
mv cargo-semver-checks ~/.cargo/bin
- name: Check semver match against the baseline branch
id: semver_check
run: |
# TODO(jayb): we are temporarily preventing a failure in semver-checks
# from showing up as a `X`, but instead triggering a comment on the
# PR. Once things go public, we will likely switch this out to make it
# actually complain as usual, possibly still keeping in the comment bot?
if [ "${{ steps.packages.outputs.has_packages }}" != "true" ]; then
: > /tmp/semver-checks-stdout
echo "Semver check skipped because no semver-relevant crate changes were detected."
echo "reaction=hooray" >> "$GITHUB_OUTPUT"
exit 0
fi
PACKAGE_ARGS=()
while IFS= read -r PACKAGE; do
PACKAGE_ARGS+=("-p" "$PACKAGE")
done < /tmp/semver-checks-packages
if cargo semver-checks "${PACKAGE_ARGS[@]}" --baseline-rev "${{ steps.baseline.outputs.ref }}" --color=never >/tmp/semver-checks-stdout; then
cat /tmp/semver-checks-stdout
echo "Semver check succeeded."
echo "reaction=hooray" >> "$GITHUB_OUTPUT"
else
cat /tmp/semver-checks-stdout
echo "Semver check failed."
echo "reaction=eyes" >> "$GITHUB_OUTPUT"
fi
# - name: React to the PR based on semver-checks
# if: ${{ github.event.pull_request }}
# run: |
# curl -L \
# -X POST \
# -H "Accept: application/vnd.github+json" \
# -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
# -H "X-GitHub-Api-Version: 2022-11-28" \
# https://api.github.com/repos/${{ github.repository_owner }}/${{ github.event.repository.name }}/issues/${{ github.event.number }}/reactions \
# -d '{"content":"${{ steps.semver_check.outputs.reaction }}"}'
- name: Delete old semver checks comments, if any
if: ${{ github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork }}
run: |
# Get the old comments
COMMENT_IDS=$(curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ github.repository_owner }}/${{ github.event.repository.name }}/issues/${{ github.event.number }}/comments | \
jq '.[] | select(.body | contains(":robot: SemverChecks :robot:")) | .id')
# Delete them all
for ID in $COMMENT_IDS; do
curl -L \
-X DELETE \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ github.repository_owner }}/${{ github.event.repository.name }}/issues/comments/$ID
done
- name: Add a new issue comment if needed
if: ${{ github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork }}
run: |
BASE_NOTE=""
if [ "${{ steps.baseline.outputs.ref }}" != "main" ] && [ "${{ steps.baseline.outputs.ref }}" != "ulitebox" ]; then
BASE_NOTE=":information_source: **Note:** This semver check was run against the \`${{ steps.baseline.outputs.ref }}\` branch, not \`main\` or \`ulitebox\`.\n\n"
fi
if [ "${{ steps.packages.outputs.has_packages }}" != "true" ]; then
BODY="$(echo -e "${BASE_NOTE}"':robot: SemverChecks :robot: No semver-relevant crate changes detected; skipped cargo-semver-checks.')"
elif [ -s /tmp/semver-checks-stdout ]; then
BODY="$(echo -e "${BASE_NOTE}"':robot: SemverChecks :robot: :warning: Potential breaking API changes detected :warning:\n\n<details><summary>Click for details</summary>\n\n```'"$(cat /tmp/semver-checks-stdout)"'\n```\n</details>')"
else
BODY="$(echo -e "${BASE_NOTE}"':robot: SemverChecks :robot: No breaking API changes detected\n\nNote: this does not mean API is unchanged, or even that there are no breaking changes; simply, none of the detections triggered.')"
fi
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ github.repository_owner }}/${{ github.event.repository.name }}/issues/${{ github.event.number }}/comments \
-d "$(printf '%s' "$BODY" | jq -sR '{body: .}')"
- name: Require documentation from fork
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork }}
env:
API_URL: ${{ github.api_url }}
REPOSITORY: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
set -euo pipefail
BASE_NOTE=""
if [ "${{ steps.baseline.outputs.ref }}" != "main" ] && [ "${{ steps.baseline.outputs.ref }}" != "ulitebox" ]; then
BASE_NOTE=":information_source: **Note:** This semver check was run against the \`${{ steps.baseline.outputs.ref }}\` branch, not \`main\` or \`ulitebox\`.\n\n"
fi
if [ "${{ steps.packages.outputs.has_packages }}" != "true" ]; then
BODY="$(echo -e "${BASE_NOTE}"':robot: SemverChecks :robot: No semver-relevant crate changes detected; skipped cargo-semver-checks.')"
elif [ -s /tmp/semver-checks-stdout ]; then
BODY="$(echo -e "${BASE_NOTE}"':robot: SemverChecks :robot: :warning: Potential breaking API changes detected :warning:\n\n<details><summary>Click for details</summary>\n\n```'"$(cat /tmp/semver-checks-stdout)"'\n```\n</details>')"
else
BODY="$(echo -e "${BASE_NOTE}"':robot: SemverChecks :robot: No breaking API changes detected\n\nNote: this does not mean API is unchanged, or even that there are no breaking changes; simply, none of the detections triggered.')"
fi
PREFIX='Documenting semver-checks CI text here:'
COMMENTS=$(curl --fail-with-body -sS \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H 'Accept: application/vnd.github+json' \
"$API_URL/repos/$REPOSITORY/issues/$PR_NUMBER/comments?per_page=100&sort=created&direction=desc")
HAS_SEMVER_COMMENT=$(jq -r '[.[] | select(.body | contains(":robot: SemverChecks :robot:"))] | length > 0' <<<"$COMMENTS")
if [ "$HAS_SEMVER_COMMENT" = "false" ] && [ ! -s /tmp/semver-checks-stdout ]; then
echo 'No breaking changes and no prior semver-checks comment; documentation is unnecessary.'
exit 0
fi
LAST=$(jq -r --arg prefix "$PREFIX" '[.[] | select(.body | startswith($prefix))] | last | if . then .body else "" end' <<<"$COMMENTS")
EXPECTED=$(printf '%s\n\n%s' "$PREFIX" "$BODY")
if [ "$LAST" != "$EXPECTED" ]; then
echo 'The latest semver documentation comment is missing or out of date.' >&2
{
printf '## Semver-checks documentation required\n\n'
printf 'Copy and paste the following as a comment on the PR (not in the PR description):\n\n'
printf '````markdown\n%s\n````\n' "$EXPECTED"
} >> "$GITHUB_STEP_SUMMARY"
printf '\nCopy and paste this as a comment on the PR (not in the PR description):\n\n```markdown\n%s\n```\n' "$EXPECTED"
exit 1
fi