Skip to content
Draft
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
84 changes: 75 additions & 9 deletions .github/workflows/test-all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,31 @@ on:
required: false
type: string
default: https://github.com/gap-system/gap.git
which-gap-sha:
description: 'Exact GAP commit SHA expected at the branch head'
required: false
type: string
default: ""
report-key:
description: 'Identifier used for artifacts and report paths'
required: false
type: string
default: ""
report-label:
description: 'Human-readable GAP label for the generated report'
required: false
type: string
default: ""
baseline-key:
description: 'Baseline key used for latest-* comparisons'
required: false
type: string
default: ""
job-name-prefix:
description: 'Reusable workflow job prefix override'
required: false
type: string
default: ""
pkg-build-glob:
description: 'Only build packages matching the given glob'
required: false
Expand Down Expand Up @@ -53,6 +78,31 @@ on:
required: false
type: string
default: https://github.com/gap-system/gap.git
which-gap-sha:
description: 'Exact GAP commit SHA expected at the branch head'
required: false
type: string
default: ""
report-key:
description: 'Identifier used for artifacts and report paths'
required: false
type: string
default: ""
report-label:
description: 'Human-readable GAP label for the generated report'
required: false
type: string
default: ""
baseline-key:
description: 'Baseline key used for latest-* comparisons'
required: false
type: string
default: ""
job-name-prefix:
description: 'Reusable workflow job prefix override'
required: false
type: string
default: ""
pkg-build-glob:
description: 'Only build packages matching the given glob'
required: false
Expand Down Expand Up @@ -130,16 +180,25 @@ jobs:
echo "::group::fetch"
whichgap="${{ github.event.inputs.which-gap || inputs.which-gap }}"
whichgaprepo="${{ github.event.inputs.which-gap-repo || inputs.which-gap-repo }}"
if [[ "${whichgap}" == 4.* ]]; then
whichgapsha="${{ github.event.inputs.which-gap-sha || inputs.which-gap-sha }}"
if [[ "${whichgap}" == 4.* && -z "${whichgapsha}" ]]; then
# assume it is a tag
wget --quiet https://github.com/gap-system/gap/releases/download/v${whichgap}/gap-${whichgap}-core.tar.gz
tar xf gap-${whichgap}-core.tar.gz
rm gap-${whichgap}-core.tar.gz
mv gap-${whichgap} $HOME/gap
else
git clone --depth=2 -b ${whichgap} ${whichgaprepo} $HOME/gap
git clone --depth=1 -b "${whichgap}" "${whichgaprepo}" $HOME/gap
fi
cd $HOME/gap
if [[ -n "${whichgapsha}" ]]; then
actualsha=$(git rev-parse HEAD)
if [[ "${actualsha}" != "${whichgapsha}" ]]; then
echo "Expected GAP branch head ${whichgapsha}, got ${actualsha}."
echo "The pull request changed after this run was requested."
exit 1
fi
fi
echo "::endgroup::"

echo "::group::autogen"
Expand Down Expand Up @@ -209,7 +268,8 @@ jobs:
- name: "Compute suitable artifact basename"
id: get-artifact-name
run: |
echo "artifact=${{ github.event.inputs.which-gap || inputs.which-gap }}" | sed -e 's;/;-;g' >> $GITHUB_OUTPUT
artifact_key="${{ github.event.inputs.report-key || inputs.report-key || github.event.inputs.which-gap || inputs.which-gap }}"
echo "artifact=${artifact_key}" | sed -e 's;/;-;g' >> $GITHUB_OUTPUT

- name: "Upload GAP with packages as artifact"
uses: actions/upload-artifact@v7
Expand Down Expand Up @@ -369,15 +429,18 @@ jobs:
- name: "Generate test-status.json"
id: test-status
run: |
# Is this a workflow_call?
if [ "${{inputs.which-gap}}" != "" ]; then
JOB_NAME_PREFIX="${{inputs.which-gap}} / "
REPORT_KEY="${{ github.event.inputs.report-key || inputs.report-key || github.event.inputs.which-gap || inputs.which-gap }}"
REPORT_LABEL="${{ github.event.inputs.report-label || inputs.report-label || github.event.inputs.which-gap || inputs.which-gap }}"
if [ "${{ inputs.job-name-prefix }}" != "" ]; then
JOB_NAME_PREFIX="${{ inputs.job-name-prefix }} / "
elif [ "${{ inputs.which-gap }}" != "" ]; then
JOB_NAME_PREFIX="${{ inputs.which-gap }} / "
else
JOB_NAME_PREFIX=""
fi
ROOT='data/reports'
# relative path (with respect to ROOT) to generated test-status.json, i.e. the "id" entry of the json-file.
DIR_REL=$(tools/generate_test_status.py ${{secrets.GITHUB_TOKEN}} ${{ github.repository }} "$GITHUB_RUN_ID" "$GITHUB_SHA" ${{ github.event.inputs.which-gap || inputs.which-gap }} "$JOB_NAME_PREFIX")
DIR_REL=$(tools/generate_test_status.py ${{secrets.GITHUB_TOKEN}} ${{ github.repository }} "$GITHUB_RUN_ID" "$GITHUB_SHA" "${REPORT_KEY}" "${REPORT_LABEL}" "${JOB_NAME_PREFIX}")
DIR="${ROOT}/${DIR_REL}"
echo "dir=${DIR}" >> $GITHUB_OUTPUT
echo "dir-rel=${DIR_REL}" >> $GITHUB_OUTPUT
Expand All @@ -386,7 +449,8 @@ jobs:
id: download-latest-report
run: |
ROOT="data/reports"
DIR_SYM_REL=latest-${{ needs.build.outputs.artifact }}
BASELINE_KEY="${{ github.event.inputs.baseline-key || inputs.baseline-key || github.event.inputs.report-key || inputs.report-key || github.event.inputs.which-gap || inputs.which-gap }}"
DIR_SYM_REL=latest-${BASELINE_KEY}
DIR_SYM="${ROOT}/${DIR_SYM_REL}"
URL_SYM="https://raw.githubusercontent.com/${{ github.repository }}/${DIR_SYM}"
# Check if file at url exists,
Expand All @@ -405,7 +469,9 @@ jobs:

- name: "Generate report"
id: report
run: tools/generate_report.py ${{ steps.test-status.outputs.dir-rel }} latest-${{ needs.build.outputs.artifact }}
run: |
BASELINE_KEY="${{ github.event.inputs.baseline-key || inputs.baseline-key || github.event.inputs.report-key || inputs.report-key || github.event.inputs.which-gap || inputs.which-gap }}"
tools/generate_report.py ${{ steps.test-status.outputs.dir-rel }} latest-${BASELINE_KEY}

- name: "Upload report as artifact"
uses: actions/upload-artifact@v7
Expand Down
200 changes: 200 additions & 0 deletions .github/workflows/test-gap-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
#
# This workflow resolves a GAP pull request URL, runs the full PackageDistro
# test suite against the pull request head, and posts a summary comment back
# to the pull request.
#
name: "Test GAP pull request"

on:
workflow_dispatch:
inputs:
gap-pr-url:
description: 'URL of a pull request on gap-system/gap'
required: true
type: string
pkg-build-glob:
description: 'Only build packages matching the given glob'
required: false
type: string
default: "*"
pkg-test-glob:
description: 'Only test packages matching the given glob'
required: false
type: string
default: "*"
callback-repo:
description: 'Optional repo to comment on, e.g. gap-system/gap'
required: false
type: string
default: ""
callback-pr-number:
description: 'Optional PR number override for callback comments'
required: false
type: string
default: ""
callback-comment-id:
description: 'Optional existing comment id to update'
required: false
type: string
default: ""
requester:
description: 'Optional login of the user who requested the run'
required: false
type: string
default: ""
command:
description: 'Optional command string that triggered the run'
required: false
type: string
default: ""

concurrency:
group: ${{ github.workflow }}-${{ github.event.inputs.gap-pr-url }}
cancel-in-progress: true

jobs:
resolve:
name: "Resolve GAP pull request"
runs-on: ubuntu-slim
outputs:
repo-owner: ${{ steps.resolve.outputs.repo-owner }}
repo-name: ${{ steps.resolve.outputs.repo-name }}
repo-full-name: ${{ steps.resolve.outputs.repo-full-name }}
pr-number: ${{ steps.resolve.outputs.pr-number }}
pr-url: ${{ steps.resolve.outputs.pr-url }}
base-ref: ${{ steps.resolve.outputs.base-ref }}
head-ref: ${{ steps.resolve.outputs.head-ref }}
head-sha: ${{ steps.resolve.outputs.head-sha }}
head-repo-clone-url: ${{ steps.resolve.outputs.head-repo-clone-url }}
report-key: ${{ steps.resolve.outputs.report-key }}
report-label: ${{ steps.resolve.outputs.report-label }}
report-artifact: ${{ steps.resolve.outputs.report-artifact }}
job-name-prefix: ${{ steps.resolve.outputs.job-name-prefix }}
callback-repo-owner: ${{ steps.resolve.outputs.callback-repo-owner }}
callback-repo-name: ${{ steps.resolve.outputs.callback-repo-name }}
callback-pr-number: ${{ steps.resolve.outputs.callback-pr-number }}
callback-comment-id: ${{ steps.resolve.outputs.callback-comment-id }}
requester: ${{ steps.resolve.outputs.requester }}
command: ${{ steps.resolve.outputs.command }}
steps:
- uses: actions/checkout@v6

- name: "Set up Python"
uses: actions/setup-python@v6
with:
python-version: "3.11"

- name: "Install package distribution tools"
run: python -m pip install -r tools/requirements.txt

- name: "Resolve GAP PR metadata"
id: resolve
run: |
python tools/gap_pr_utils.py "${{ github.event.inputs.gap-pr-url }}" > resolved.json

callback_repo="${{ github.event.inputs.callback-repo }}"
if [[ -n "${callback_repo}" ]]; then
callback_repo_owner="${callback_repo%%/*}"
callback_repo_name="${callback_repo##*/}"
else
callback_repo_owner=$(jq -r '.repo_owner' resolved.json)
callback_repo_name=$(jq -r '.repo_name' resolved.json)
fi

callback_pr_number="${{ github.event.inputs.callback-pr-number }}"
if [[ -z "${callback_pr_number}" ]]; then
callback_pr_number=$(jq -r '.number' resolved.json)
fi

echo "repo-owner=$(jq -r '.repo_owner' resolved.json)" >> $GITHUB_OUTPUT
echo "repo-name=$(jq -r '.repo_name' resolved.json)" >> $GITHUB_OUTPUT
echo "repo-full-name=$(jq -r '.repo_full_name' resolved.json)" >> $GITHUB_OUTPUT
echo "pr-number=$(jq -r '.number' resolved.json)" >> $GITHUB_OUTPUT
echo "pr-url=$(jq -r '.pr_url' resolved.json)" >> $GITHUB_OUTPUT
echo "base-ref=$(jq -r '.base_ref' resolved.json)" >> $GITHUB_OUTPUT
echo "head-ref=$(jq -r '.head_ref' resolved.json)" >> $GITHUB_OUTPUT
echo "head-sha=$(jq -r '.head_sha' resolved.json)" >> $GITHUB_OUTPUT
echo "head-repo-clone-url=$(jq -r '.head_repo_clone_url' resolved.json)" >> $GITHUB_OUTPUT
echo "report-key=$(jq -r '.report_key' resolved.json)" >> $GITHUB_OUTPUT
echo "report-label=$(jq -r '.report_label' resolved.json)" >> $GITHUB_OUTPUT
echo "report-artifact=$(jq -r '.report_key' resolved.json)" >> $GITHUB_OUTPUT
echo "job-name-prefix=$(jq -r '.job_name_prefix' resolved.json)" >> $GITHUB_OUTPUT
echo "callback-repo-owner=${callback_repo_owner}" >> $GITHUB_OUTPUT
echo "callback-repo-name=${callback_repo_name}" >> $GITHUB_OUTPUT
echo "callback-pr-number=${callback_pr_number}" >> $GITHUB_OUTPUT
echo "callback-comment-id=${{ github.event.inputs.callback-comment-id }}" >> $GITHUB_OUTPUT
echo "requester=${{ github.event.inputs.requester }}" >> $GITHUB_OUTPUT
echo "command=${{ github.event.inputs.command }}" >> $GITHUB_OUTPUT

test-gap-pr:
name: ${{ needs.resolve.outputs.job-name-prefix }}
needs: resolve
uses: ./.github/workflows/test-all.yml
with:
which-gap: ${{ needs.resolve.outputs.head-ref }}
which-gap-repo: ${{ needs.resolve.outputs.head-repo-clone-url }}
which-gap-sha: ${{ needs.resolve.outputs.head-sha }}
report-key: ${{ needs.resolve.outputs.report-key }}
report-label: ${{ needs.resolve.outputs.report-label }}
baseline-key: ${{ needs.resolve.outputs.base-ref }}
job-name-prefix: ${{ needs.resolve.outputs.job-name-prefix }}
pkg-build-glob: ${{ github.event.inputs.pkg-build-glob }}
pkg-test-glob: ${{ github.event.inputs.pkg-test-glob }}

comment:
name: "Comment on GAP pull request"
needs: [resolve, test-gap-pr]
if: always()
runs-on: ubuntu-slim
steps:
- uses: actions/checkout@v6

- name: "Set up Python"
uses: actions/setup-python@v6
with:
python-version: "3.11"

- name: "Install package distribution tools"
run: python -m pip install -r tools/requirements.txt

- name: "Download report"
uses: actions/download-artifact@v8
with:
name: report-${{ needs.resolve.outputs.report-artifact }}
path: _report

- name: "Build comment body"
run: |
mkdir -p _comment
cat > _comment/metadata.json <<EOF
{
"pr_url": "${{ needs.resolve.outputs.pr-url }}",
"repo_full_name": "${{ needs.resolve.outputs.repo-full-name }}",
"number": ${{ needs.resolve.outputs.callback-pr-number }},
"head_sha": "${{ needs.resolve.outputs.head-sha }}",
"requester": "${{ needs.resolve.outputs.requester }}",
"command": "${{ needs.resolve.outputs.command }}"
}
EOF
python tools/render_gap_pr_test_comment.py \
_comment/metadata.json \
_report/test-status.json \
_report/test-status-diff.json \
_report/report.md > _comment/body.md

- uses: actions/create-github-app-token@v3
id: generate-token
with:
client-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: ${{ needs.resolve.outputs.callback-repo-owner }}
repositories: ${{ needs.resolve.outputs.callback-repo-name }}

- name: "Create or update comment"
uses: peter-evans/create-or-update-comment@v5
with:
token: ${{ steps.generate-token.outputs.token }}
issue-number: ${{ needs.resolve.outputs.callback-pr-number }}
comment-id: ${{ needs.resolve.outputs.callback-comment-id }}
body-path: _comment/body.md
edit-mode: replace
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,22 @@ a report is added to the PR which indicates whether the new package breaks somet
in GAP or other packages, and whether its tests pass. If all looks good, the
PR may be merged by any maintainer.

### Testing GAP pull requests against all packages

Maintainers can also run the full PackageDistro test suite against a pull
request on `gap-system/gap`.

1. Go to
<https://github.com/gap-system/PackageDistro/actions/workflows/test-gap-pr.yml>
2. Click "Run workflow".
3. Paste the GAP pull request URL into the `gap-pr-url` field.
4. Optionally restrict the package build or test glob.

The workflow resolves the pull request automatically, checks out the exact
head revision, compares the results against the latest report for the pull
request's target branch, and posts a summary comment back to the GAP pull
request.


## How everything works

Expand Down
Loading