mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-07 05:22:56 +00:00
## Problem
`github.sha` contains a merge commit of `head` and `base` if we're in a
PR. In release PRs, this makes no sense, because we fast-forward the
`base` branch to contain the changes from `head`.
Even though we correctly use `${{ github.event.pull_request.head.sha ||
github.sha }}` to reference the git commit when building artifacts, we
don't use that when checking out code, because we want to test the merge
of head and base usually. In the case of release PRs, we definitely
always want to test on the head sha though, because we're going to
forward that, and it already has the base sha as a parent, so the merge
would end up with the same tree anyway.
As a side effect, not checking out `${{
github.event.pull_request.head.sha || github.sha }}` also caused
https://github.com/neondatabase/neon/actions/runs/13986389780/job/39173256184#step:6:49
to say `release-tag=release-compute-8187`, while
https://github.com/neondatabase/neon/actions/runs/14084613121/job/39445314780#step:6:48
is talking about `build-tag=release-compute-8186`
## Summary of changes
Run a few things on `github.event.pull_request.head.sha`, if we're in a
release PR.
164 lines
6.4 KiB
YAML
164 lines
6.4 KiB
YAML
name: Trigger E2E Tests
|
|
|
|
on:
|
|
pull_request:
|
|
types:
|
|
- ready_for_review
|
|
workflow_call:
|
|
inputs:
|
|
github-event-name:
|
|
type: string
|
|
required: true
|
|
github-event-json:
|
|
type: string
|
|
required: true
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash -euxo pipefail {0}
|
|
|
|
env:
|
|
# A concurrency group that we use for e2e-tests runs, matches `concurrency.group` above with `github.repository` as a prefix
|
|
E2E_CONCURRENCY_GROUP: ${{ github.repository }}-e2e-tests-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }}
|
|
|
|
jobs:
|
|
check-permissions:
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'run-no-ci') }}
|
|
uses: ./.github/workflows/check-permissions.yml
|
|
with:
|
|
github-event-name: ${{ inputs.github-event-name || github.event_name }}
|
|
|
|
cancel-previous-e2e-tests:
|
|
needs: [ check-permissions ]
|
|
if: github.event_name == 'pull_request'
|
|
runs-on: ubuntu-22.04
|
|
|
|
steps:
|
|
- name: Harden the runner (Audit all outbound calls)
|
|
uses: step-security/harden-runner@v2
|
|
with:
|
|
egress-policy: audit
|
|
|
|
- name: Cancel previous e2e-tests runs for this PR
|
|
env:
|
|
GH_TOKEN: ${{ secrets.CI_ACCESS_TOKEN }}
|
|
run: |
|
|
gh workflow --repo neondatabase/cloud \
|
|
run cancel-previous-in-concurrency-group.yml \
|
|
--field concurrency_group="${{ env.E2E_CONCURRENCY_GROUP }}"
|
|
|
|
meta:
|
|
uses: ./.github/workflows/_meta.yml
|
|
with:
|
|
github-event-name: ${{ inputs.github-event-name || github.event_name }}
|
|
github-event-json: ${{ inputs.github-event-json || toJSON(github.event) }}
|
|
|
|
trigger-e2e-tests:
|
|
needs: [ meta ]
|
|
runs-on: ubuntu-22.04
|
|
env:
|
|
EVENT_ACTION: ${{ github.event.action }}
|
|
GH_TOKEN: ${{ secrets.CI_ACCESS_TOKEN }}
|
|
TAG: >-
|
|
${{
|
|
contains(fromJSON('["compute-release", "compute-rc-pr"]'), needs.meta.outputs.run-kind)
|
|
&& needs.meta.outputs.previous-storage-release
|
|
|| needs.meta.outputs.build-tag
|
|
}}
|
|
COMPUTE_TAG: >-
|
|
${{
|
|
contains(fromJSON('["storage-release", "storage-rc-pr", "proxy-release", "proxy-rc-pr"]'), needs.meta.outputs.run-kind)
|
|
&& needs.meta.outputs.previous-compute-release
|
|
|| needs.meta.outputs.build-tag
|
|
}}
|
|
steps:
|
|
- name: Harden the runner (Audit all outbound calls)
|
|
uses: step-security/harden-runner@v2
|
|
with:
|
|
egress-policy: audit
|
|
|
|
- name: Wait for `push-{neon,compute}-image-dev` job to finish
|
|
# It's important to have a timeout here, the script in the step can run infinitely
|
|
timeout-minutes: 60
|
|
run: |
|
|
if [ "${GITHUB_EVENT_NAME}" != "pull_request" ] || [ "${EVENT_ACTION}" != "ready_for_review" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
# For PRs we use the run id as the tag
|
|
BUILD_AND_TEST_RUN_ID=${TAG}
|
|
while true; do
|
|
gh run --repo ${GITHUB_REPOSITORY} view ${BUILD_AND_TEST_RUN_ID} --json jobs --jq '[.jobs[] | select((.name | startswith("push-neon-image-dev")) or (.name | startswith("push-compute-image-dev"))) | {"name": .name, "conclusion": .conclusion, "url": .url}]' > jobs.json
|
|
if [ $(jq '[.[] | select(.conclusion == "success")] | length' jobs.json) -eq 2 ]; then
|
|
break
|
|
fi
|
|
jq -c '.[]' jobs.json | while read -r job; do
|
|
case $(echo $job | jq .conclusion) in
|
|
failure | cancelled | skipped)
|
|
echo "The '$(echo $job | jq .name)' job didn't succeed: '$(echo $job | jq .conclusion)'. See log in '$(echo $job | jq .url)' Exiting..."
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
echo "The 'push-{neon,compute}-image-dev' jobs haven't succeeded yet. Waiting..."
|
|
sleep 60
|
|
done
|
|
|
|
- name: Set e2e-platforms
|
|
id: e2e-platforms
|
|
env:
|
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
# Default set of platforms to run e2e tests on
|
|
platforms='["docker", "k8s"]'
|
|
|
|
# If a PR changes anything that affects computes, add k8s-neonvm to the list of platforms.
|
|
# If the workflow run is not a pull request, add k8s-neonvm to the list.
|
|
if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then
|
|
for f in $(gh api "/repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/files" --paginate --jq '.[].filename'); do
|
|
case "$f" in
|
|
# List of directories that contain code which affect compute images.
|
|
#
|
|
# This isn't exhaustive, just the paths that are most directly compute-related.
|
|
# For example, compute_ctl also depends on libs/utils, but we don't trigger
|
|
# an e2e run on that.
|
|
vendor/*|pgxn/*|compute_tools/*|libs/vm_monitor/*|compute/compute-node.Dockerfile)
|
|
platforms=$(echo "${platforms}" | jq --compact-output '. += ["k8s-neonvm"] | unique')
|
|
;;
|
|
*)
|
|
# no-op
|
|
;;
|
|
esac
|
|
done
|
|
else
|
|
platforms=$(echo "${platforms}" | jq --compact-output '. += ["k8s-neonvm"] | unique')
|
|
fi
|
|
|
|
echo "e2e-platforms=${platforms}" | tee -a $GITHUB_OUTPUT
|
|
|
|
- name: Set PR's status to pending and request a remote CI test
|
|
env:
|
|
E2E_PLATFORMS: ${{ steps.e2e-platforms.outputs.e2e-platforms }}
|
|
COMMIT_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
|
|
GH_TOKEN: ${{ secrets.CI_ACCESS_TOKEN }}
|
|
run: |
|
|
REMOTE_REPO="${GITHUB_REPOSITORY_OWNER}/cloud"
|
|
|
|
gh api "/repos/${GITHUB_REPOSITORY}/statuses/${COMMIT_SHA}" \
|
|
--method POST \
|
|
--raw-field "state=pending" \
|
|
--raw-field "description=[$REMOTE_REPO] Remote CI job is about to start" \
|
|
--raw-field "context=neon-cloud-e2e"
|
|
|
|
gh workflow --repo ${REMOTE_REPO} \
|
|
run testing.yml \
|
|
--ref "main" \
|
|
--raw-field "ci_job_name=neon-cloud-e2e" \
|
|
--raw-field "commit_hash=$COMMIT_SHA" \
|
|
--raw-field "remote_repo=${GITHUB_REPOSITORY}" \
|
|
--raw-field "storage_image_tag=${TAG}" \
|
|
--raw-field "compute_image_tag=${COMPUTE_TAG}" \
|
|
--raw-field "concurrency_group=${E2E_CONCURRENCY_GROUP}" \
|
|
--raw-field "e2e-platforms=${E2E_PLATFORMS}"
|