Skip to content

Commit 8b31eaf

Browse files
authored
chore: harden actions trust boundaries (#2788)
1 parent 252a657 commit 8b31eaf

4 files changed

Lines changed: 167 additions & 10 deletions

File tree

.github/workflows/build.yaml

Lines changed: 133 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ concurrency:
1919

2020
jobs:
2121
build:
22+
if: github.event_name == 'pull_request'
2223
runs-on: ubuntu-latest
24+
env:
25+
CACHE_TRUST_PREFIX: pr
2326
permissions:
2427
contents: read
25-
packages: write
26-
attestations: write
27-
id-token: write
2828

2929
strategy:
3030
fail-fast: false
@@ -46,9 +46,9 @@ jobs:
4646
- uses: actions/cache@v5
4747
with:
4848
path: uv.lock
49-
key: ${{ matrix.python-version }}-uv-lock-${{ hashFiles('pyproject.toml') }}
49+
key: ${{ env.CACHE_TRUST_PREFIX }}-${{ matrix.python-version }}-uv-lock-${{ hashFiles('pyproject.toml') }}
5050
restore-keys: |
51-
${{ matrix.python-version }}-uv-lock-
51+
${{ env.CACHE_TRUST_PREFIX }}-${{ matrix.python-version }}-uv-lock-
5252
- run: uv lock --python ${{ matrix.python-version }}
5353

5454
- name: Get version from setuptools-scm
@@ -131,8 +131,8 @@ jobs:
131131
push: ${{ github.event_name != 'pull_request' }}
132132
tags: ${{ steps.meta.outputs.tags }}
133133
labels: ${{ steps.meta.outputs.labels }}
134-
cache-from: type=gha,scope=build-py${{ matrix.python-version }}-${{ matrix.target }}
135-
cache-to: type=gha,mode=max,scope=build-py${{ matrix.python-version }}-${{ matrix.target }}
134+
cache-from: type=gha,scope=${{ env.CACHE_TRUST_PREFIX }}-build-py${{ matrix.python-version }}-${{ matrix.target }}
135+
cache-to: type=gha,mode=max,scope=${{ env.CACHE_TRUST_PREFIX }}-build-py${{ matrix.python-version }}-${{ matrix.target }}
136136
platforms: ${{ github.event_name != 'pull_request' && 'linux/amd64,linux/arm64' || 'linux/amd64' }}
137137

138138
- name: Run container retention policy
@@ -148,3 +148,129 @@ jobs:
148148
tag-selection: both
149149
cut-off: 4w
150150
dry-run: ${{ github.ref != 'refs/heads/main' }}
151+
152+
publish:
153+
if: github.event_name != 'pull_request'
154+
runs-on: ubuntu-latest
155+
env:
156+
CACHE_TRUST_PREFIX: trusted
157+
permissions:
158+
contents: read
159+
packages: write
160+
attestations: write
161+
id-token: write
162+
163+
strategy:
164+
fail-fast: false
165+
matrix:
166+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
167+
target: ["slim", "full"]
168+
169+
steps:
170+
- name: Checkout repository
171+
uses: actions/checkout@v5
172+
with:
173+
fetch-depth: 0 # Needed for setuptools-scm
174+
175+
# NOTE: We need to store `uv.lock` for building with
176+
- uses: astral-sh/setup-uv@v7
177+
- uses: actions/cache@v5
178+
with:
179+
path: uv.lock
180+
key: ${{ env.CACHE_TRUST_PREFIX }}-${{ matrix.python-version }}-uv-lock-${{ hashFiles('pyproject.toml') }}
181+
restore-keys: |
182+
${{ env.CACHE_TRUST_PREFIX }}-${{ matrix.python-version }}-uv-lock-
183+
- run: uv lock --python ${{ matrix.python-version }}
184+
185+
- name: Get version from setuptools-scm
186+
id: version
187+
run: |
188+
VERSION=$(uvx setuptools-scm)
189+
echo "version=${VERSION}" >> $GITHUB_OUTPUT
190+
191+
- name: Check if default Python version
192+
id: is-default
193+
run: |
194+
if [ "${{ matrix.python-version }}" = "${{ env.DEFAULT_PYTHON }}" ]; then
195+
echo "value=true" >> $GITHUB_OUTPUT
196+
else
197+
echo "value=false" >> $GITHUB_OUTPUT
198+
fi
199+
200+
- name: Set up Docker Buildx
201+
uses: docker/setup-buildx-action@v3
202+
203+
- name: Log into GitHub Container Registry
204+
uses: docker/login-action@v3
205+
with:
206+
registry: ${{ env.REGISTRY }}
207+
username: ${{ github.actor }}
208+
password: ${{ secrets.GITHUB_TOKEN }}
209+
210+
- name: Generate Docker metadata
211+
id: meta
212+
uses: docker/metadata-action@v5
213+
with:
214+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
215+
flavor: |
216+
latest=false
217+
suffix=${{ matrix.target == 'slim' && '-slim' || ''}}
218+
# NOTE: `latest=false` lets us manage it better here
219+
tags: |
220+
# For default Python version (unprefixed convenience tags)
221+
# - 'latest' on push to main
222+
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' && steps.is-default.outputs.value == 'true' }}
223+
# - 'stable' on release
224+
type=raw,value=stable,enable=${{ github.event_name == 'release' && steps.is-default.outputs.value == 'true' }}
225+
# - version tag (e.g., v0.8.43) on release
226+
type=ref,event=tag,enable=${{ steps.is-default.outputs.value == 'true' }}
227+
228+
# For all Python versions (including default):
229+
# - 'python3.x-latest' on push to main
230+
type=raw,value=python${{ matrix.python-version }}-latest,enable=${{ github.ref == 'refs/heads/main' }}
231+
# - 'python3.x-stable' on release
232+
type=raw,value=python${{ matrix.python-version }}-stable,enable=${{ github.event_name == 'release' }}
233+
# - 'python3.x-v*' on release
234+
type=ref,event=tag,prefix=python${{ matrix.python-version }}-,enable=${{ github.event_name == 'release' }}
235+
labels: |
236+
org.opencontainers.image.title=ape
237+
org.opencontainers.image.description=Build and explore on-chain with Python
238+
org.opencontainers.image.url=https://apeworx.io/framework
239+
org.opencontainers.image.documentation=https://docs.apeworx.io/ape/stable/userguides/quickstart
240+
org.opencontainers.image.source=https://github.com/ApeWorX/ape
241+
org.opencontainers.image.vendor=ApeWorX LTD
242+
org.opencontainers.image.licenses=Apache-2.0
243+
org.opencontainers.image.version=${{ steps.version.outputs.version }}
244+
org.opencontainers.image.revision=${{ github.sha }}
245+
org.opencontainers.image.authors=ApeWorX LTD
246+
org.opencontainers.image.base.name=python:${{ matrix.python-version }}-slim
247+
248+
- name: Build and push image
249+
id: build
250+
uses: docker/build-push-action@v6
251+
with:
252+
context: .
253+
file: ./Dockerfile
254+
target: ${{ matrix.target }}
255+
build-args: |
256+
PYTHON_VERSION=${{ matrix.python-version }}
257+
APE_VERSION=${{ steps.version.outputs.version }}
258+
push: true
259+
tags: ${{ steps.meta.outputs.tags }}
260+
labels: ${{ steps.meta.outputs.labels }}
261+
cache-from: type=gha,scope=${{ env.CACHE_TRUST_PREFIX }}-build-py${{ matrix.python-version }}-${{ matrix.target }}
262+
cache-to: type=gha,mode=max,scope=${{ env.CACHE_TRUST_PREFIX }}-build-py${{ matrix.python-version }}-${{ matrix.target }}
263+
platforms: linux/amd64,linux/arm64
264+
265+
- name: Run container retention policy
266+
# TODO: Use `v3` when available
267+
uses: snok/container-retention-policy@v3.0.1
268+
with:
269+
account: ApeWorX
270+
token: ${{ secrets.GITHUB_TOKEN }}
271+
image-names: "ape"
272+
# NOTE: Keep stable/stable-slim, latest/latest-slim, all v0.8.x series, and last in v0.7.x series
273+
image-tags: "!stable* !latest* !v0.8* !v0.7.23*"
274+
tag-selection: both
275+
cut-off: 4w
276+
dry-run: ${{ github.ref != 'refs/heads/main' }}

.github/workflows/docs.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,36 @@ concurrency:
1717

1818
jobs:
1919
docs:
20+
if: github.event_name == 'pull_request'
21+
runs-on: ubuntu-latest
22+
23+
permissions:
24+
contents: read
25+
26+
steps:
27+
- uses: actions/checkout@v5
28+
29+
- name: Setup Python
30+
uses: astral-sh/setup-uv@v7
31+
with:
32+
python-version: "3.10"
33+
enable-cache: true
34+
cache-dependency-glob: pyproject.toml
35+
36+
- name: Build Docs
37+
run: uv sync
38+
39+
- name: Add venv to PATH
40+
run: echo "${{ github.workspace }}/.venv/bin" >> $GITHUB_PATH
41+
# NOTE: Otherwise the next action nukes the path when it starts
42+
43+
- name: Ape Docs
44+
uses: apeworx/sphinx-ape@main
45+
with:
46+
github-token: ${{ secrets.GITHUB_TOKEN }}
47+
48+
publish-docs:
49+
if: github.event_name != 'pull_request'
2050
runs-on: ubuntu-latest
2151

2252
permissions:

.github/workflows/publish.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@ jobs:
88
deploy:
99
runs-on: ubuntu-latest
1010
permissions:
11+
contents: read
1112
id-token: write
1213

1314
steps:
1415
- uses: actions/checkout@v5
1516
- uses: astral-sh/setup-uv@v7
16-
with:
17-
enable-cache: true
18-
cache-dependency-glob: pyproject.toml
1917

2018
- name: Build Package
2119
run: uv build

.github/workflows/test.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ on: ["push", "pull_request"]
22

33
name: Test
44

5+
permissions:
6+
contents: read
7+
58
env:
69
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_ETH_APE: "0.8.999"
710

0 commit comments

Comments
 (0)