-
Notifications
You must be signed in to change notification settings - Fork 599
140 lines (131 loc) · 6.79 KB
/
ci3-external.yml
File metadata and controls
140 lines (131 loc) · 6.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# CI for external Aztec contributors. Like ci3.yml, but more locked down.
#
# CAREFUL! We use "exec" a lot to ensure signal propagation to the child process, to allow proper ec2 cleanup.
name: CI3 (External)
on:
# This check is skipped in merge queue, but we need it to run (even skipped) for status checks.
merge_group:
# Run with pull_request_target for external devs. This forces them to use this workflow as-is.
pull_request_target:
types: [opened, synchronize, reopened, ready_for_review, labeled]
concurrency:
# Only allow one run per <forked-repo>/<branch> and full concurrency on merge queue.
group: |
ci3-external-${{ github.event_name == 'pull_request' && format('{0}/{1}', github.event.pull_request.head.repo.full_name, github.head_ref)
|| github.run_id }}
cancel-in-progress: true
jobs:
ci-external:
runs-on: ubuntu-latest
# exclusive with ci3.yml, only run on forks.
if: github.event.pull_request.head.repo.fork
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
# The commit to checkout. We want our actual commit, and not the result of merging the PR to the target.
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
# NOTE: in ci3.yml we just rely on draft mode not being mergable.
# Here we are a little more careful than just skipping the worklfow, in case of an edge case allowing merge.
- name: Fail If Draft
if: github.event.pull_request.draft
run: echo "CI is not run on drafts." && exit 1
# Gate 'ci-external' on the labeller being a member of AztecProtocol/watchers.
- name: Verify ci-external Labeller Authorization
if: contains(github.event.pull_request.labels.*.name, 'ci-external')
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
GH_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }}
run: |
set -o pipefail
# Note: pipe to jq with -s add to flatten paginated arrays; gh's own --jq runs per-page.
labeller=$(gh api --paginate "/repos/$REPO/issues/$PR_NUMBER/events" \
| jq -r -s 'add | [.[] | select(.event == "labeled" and .label.name == "ci-external")] | last | .actor.login // empty')
if [ -z "$labeller" ] || [ "$labeller" = "null" ]; then
echo "Error: could not determine who applied the 'ci-external' label. Stripping it."
gh pr edit "$PR_NUMBER" --remove-label "ci-external" || true
exit 1
fi
state=$(gh api "/orgs/AztecProtocol/teams/watchers/memberships/$labeller" --jq '.state' 2>/dev/null || true)
if [ "$state" != "active" ]; then
echo "Error: labeller is not an active member of AztecProtocol/watchers. Stripping 'ci-external' label."
gh pr edit "$PR_NUMBER" --remove-label "ci-external"
exit 1
fi
echo "Labeller is authorized."
- name: External Contributor Checks
env:
PR_BASE_REF: ${{ github.event.pull_request.base.ref }}
PR_NUMBER: ${{ github.event.pull_request.number }}
HAS_CI_LABEL: ${{ contains(github.event.pull_request.labels.*.name, 'ci-external') || github.event.label.name == 'ci-external-once' }}
GH_TOKEN: ${{ github.token }}
run: |
set -o pipefail
git fetch origin "$PR_BASE_REF" --depth=1 &>/dev/null
forbidden_changes=$(git diff --name-only "origin/$PR_BASE_REF" HEAD -- ci3 .github ci.sh scripts)
if echo "$forbidden_changes" | grep -q .; then
echo "Error: External PRs can't contain CI changes (forbidden files: $forbidden_changes)."
exit 1
fi
if [[ "$PR_BASE_REF" != "master" && \
"$PR_BASE_REF" != "staging" && \
"$PR_BASE_REF" != "next" && \
"$PR_BASE_REF" != merge-train/* ]]; then
echo "Error: External PRs can only target master, staging, next or merge-train/* branches. Targeted: $PR_BASE_REF."
exit 1
fi
if [ "$HAS_CI_LABEL" = false ]; then
echo "External PRs need the 'ci-external' or 'ci-external-once' labels to run."
exit 1
fi
gh pr edit "$PR_NUMBER" --remove-label "ci-external-once"
- name: Determine CI Mode
env:
MERGE_GROUP_BASE_REF: ${{ github.event.merge_group.base_ref }}
PR_BASE_REF: ${{ github.event.pull_request.base.ref }}
GITHUB_REF_NAME: ${{ github.ref_name }}
GITHUB_TOKEN: ${{ github.token }}
PR_LABELS_JSON: ${{ toJson(github.event.pull_request.labels.*.name) }}
run: |
# Parse labels from JSON env var to avoid shell injection via label names
mapfile -t LABELS < <(echo "$PR_LABELS_JSON" | jq -r '.[]')
./.github/ci3_labels_to_env.sh "${LABELS[@]}"
- name: Run
env:
REF_NAME: repo-fork/${{ github.repository }}/${{ github.head_ref }}
# We only test on amd64.
ARCH: amd64
# We need to pass these creds to start the AWS ec2 instance.
# They are not injected into that instance. Instead, it has minimal
# creds for being able to upload to cache.
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
GITHUB_TOKEN: ${{ github.token }}
BUILD_INSTANCE_SSH_KEY: ${{ secrets.BUILD_INSTANCE_SSH_KEY }}
# DO NOT allow build instance key access to external jobs.
CI_USE_BUILD_INSTANCE_KEY: "0"
MERGE_GROUP_BASE_REF: ${{ github.event.merge_group.base_ref }}
PR_BASE_REF: ${{ github.event.pull_request.base.ref }}
PR_HEAD_REF: ${{ github.event.pull_request.head.ref }}
PR_COMMITS: ${{ github.event.pull_request.commits }}
GITHUB_REF_NAME: ${{ github.ref_name }}
run: ./.github/ci3.sh $CI_MODE
- name: Post-Actions
if: always()
env:
SHOULD_SQUASH_MERGE: ${{ contains(github.event.pull_request.labels.*.name, 'ci-squash-and-merge') && '1' || '0' }}
SHOULD_UPLOAD_BENCHMARKS: "0"
# For updating success cache.
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
GITHUB_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_HEAD_REF: ${{ github.event.pull_request.head.ref }}
PR_BASE_REF: ${{ github.event.pull_request.base.ref }}
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
run: ./.github/ci3_success.sh