|
18 | 18 | paths: |
19 | 19 | - ".github/packaging/**" |
20 | 20 | - ".github/workflows/build-linux-packages.yml" |
21 | | - - ".github/workflows/upload-pkg-s3.yml" |
22 | 21 |
|
23 | 22 | env: |
24 | 23 | FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true |
|
47 | 46 | runs-on: ${{ matrix.runner }} |
48 | 47 | permissions: |
49 | 48 | contents: read |
| 49 | + # All four matrix legs resolve the same tag: the composite action derives |
| 50 | + # it only from the dispatch input / git ref (see workflow-setup-packaging.sh), |
| 51 | + # never from format or arch. The job output is therefore a last-writer-wins |
| 52 | + # race between legs, but every leg writes the identical value, so downstream |
| 53 | + # consumers (upload-debs-s3) read a stable tag regardless of which leg wins. |
50 | 54 | outputs: |
51 | 55 | tag: ${{ steps.build.outputs.tag }} |
52 | 56 |
|
|
55 | 59 | with: |
56 | 60 | ref: ${{ github.event.inputs.tag || github.ref }} |
57 | 61 |
|
| 62 | + # Defense in depth: workflow_dispatch accepts an arbitrary ref, and non-PR |
| 63 | + # events import the real signing key. The overlay below replaces only |
| 64 | + # .github/packaging, so the repo-root build helpers and the graft tree still |
| 65 | + # run from the checked-out ref. Refuse to proceed unless the dispatched input |
| 66 | + # names an actual tag in origin (not a branch), so the key can never sign |
| 67 | + # arbitrary branch content. |
| 68 | + # tag-push events are already constrained to refs/tags/v* by the `on:` filter. |
| 69 | + - name: Assert dispatch input is a released tag |
| 70 | + if: github.event.inputs.tag |
| 71 | + env: |
| 72 | + TAG_INPUT: ${{ github.event.inputs.tag }} |
| 73 | + shell: bash |
| 74 | + run: | |
| 75 | + if [[ ! "${TAG_INPUT}" =~ ^v[0-9] ]]; then |
| 76 | + echo "ERROR: tag input '${TAG_INPUT}' must start with 'v<digit>' (e.g. v1.14.1)" >&2 |
| 77 | + exit 1 |
| 78 | + fi |
| 79 | + if ! git ls-remote --exit-code --tags origin "refs/tags/${TAG_INPUT}" >/dev/null; then |
| 80 | + echo "ERROR: '${TAG_INPUT}' is not a tag in origin; refusing to build/sign a non-tag ref" >&2 |
| 81 | + exit 1 |
| 82 | + fi |
| 83 | +
|
58 | 84 | # When building an older tag via workflow_dispatch, the tag's |
59 | 85 | # .github/packaging tree may be stale or absent. Replace it |
60 | 86 | # wholesale with the workflow branch's version so that this build |
@@ -88,35 +114,51 @@ jobs: |
88 | 114 | gpg-passphrase: ${{ github.event_name != 'pull_request' && secrets.RPM_GPG_PASSPHRASE || '' }} |
89 | 115 | release: ${{ github.event_name != 'pull_request' && 'true' || 'false' }} |
90 | 116 |
|
91 | | - # Release-only S3 upload. Delegates to the shared upload-pkg-s3 |
92 | | - # workflow so id-token: write stays scoped to that workflow's job — |
93 | | - # never granted to a job that checks out a tag tree and runs |
94 | | - # packaging scripts. |
95 | | - upload-s3: |
| 117 | + # Release-only DEB S3 upload. Runs in its own job so id-token: write is |
| 118 | + # never granted to a job that checks out and executes PR-controlled |
| 119 | + # packaging scripts. RPM S3 publishing can land as a sibling job later. |
| 120 | + upload-debs-s3: |
96 | 121 | needs: build |
97 | 122 | if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) || github.event_name == 'workflow_dispatch' |
| 123 | + strategy: |
| 124 | + matrix: |
| 125 | + deb_arch: [amd64, arm64] |
| 126 | + runs-on: ubuntu-22.04 |
98 | 127 | permissions: |
99 | 128 | id-token: write |
100 | 129 | contents: read |
101 | | - strategy: |
102 | | - matrix: |
103 | | - include: |
104 | | - - pkg-format: deb |
105 | | - arches: '["amd64","arm64"]' |
106 | | - distros: jammy noble |
107 | | - s3-prefix: linux/debs/ubuntu |
108 | | - - pkg-format: rpm |
109 | | - arches: '["x86_64","aarch64"]' |
110 | | - distros: el9 |
111 | | - s3-prefix: linux/rpms/rhel |
112 | | - uses: ./.github/workflows/upload-pkg-s3.yml |
113 | | - with: |
114 | | - pkg-format: ${{ matrix.pkg-format }} |
115 | | - tag: ${{ needs.build.outputs.tag }} |
116 | | - arches: ${{ matrix.arches }} |
117 | | - packages: avalanchego subnet-evm |
118 | | - distros: ${{ matrix.distros }} |
119 | | - s3-prefix: ${{ matrix.s3-prefix }} |
120 | | - secrets: |
121 | | - AWS_ROLE_ARN: ${{ secrets.AWS_DEPLOY_SA_ROLE_ARN }} |
122 | | - BUCKET: ${{ secrets.BUCKET }} |
| 130 | + |
| 131 | + steps: |
| 132 | + - name: Download DEB artifacts |
| 133 | + uses: actions/download-artifact@v6 |
| 134 | + with: |
| 135 | + name: debs-${{ matrix.deb_arch }} |
| 136 | + path: build/deb |
| 137 | + |
| 138 | + - name: Configure AWS credentials |
| 139 | + uses: aws-actions/configure-aws-credentials@v6 |
| 140 | + with: |
| 141 | + role-to-assume: ${{ secrets.AWS_DEPLOY_SA_ROLE_ARN }} |
| 142 | + role-session-name: githubrolesession |
| 143 | + aws-region: us-east-1 |
| 144 | + |
| 145 | + - name: Install aws cli |
| 146 | + run: | |
| 147 | + if ! command -v aws &>/dev/null; then |
| 148 | + sudo snap install aws-cli --classic |
| 149 | + fi |
| 150 | +
|
| 151 | + - name: Upload DEBs to S3 |
| 152 | + env: |
| 153 | + TAG: ${{ needs.build.outputs.tag }} |
| 154 | + DEB_ARCH: ${{ matrix.deb_arch }} |
| 155 | + BUCKET: ${{ secrets.BUCKET }} |
| 156 | + run: | |
| 157 | + for release in jammy noble; do |
| 158 | + aws s3 cp "build/deb/avalanchego-${TAG}-${DEB_ARCH}.deb" \ |
| 159 | + "s3://${BUCKET}/linux/debs/ubuntu/${release}/${DEB_ARCH}/" |
| 160 | + aws s3 cp "build/deb/subnet-evm-${TAG}-${DEB_ARCH}.deb" \ |
| 161 | + "s3://${BUCKET}/linux/debs/ubuntu/${release}/${DEB_ARCH}/" |
| 162 | + aws s3 cp "build/deb/GPG-KEY-avalanchego" \ |
| 163 | + "s3://${BUCKET}/linux/debs/ubuntu/${release}/" |
| 164 | + done |
0 commit comments