-
Notifications
You must be signed in to change notification settings - Fork 14
154 lines (138 loc) · 6.04 KB
/
deploy-image.yml
File metadata and controls
154 lines (138 loc) · 6.04 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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
name: Docker image — build, test, publish
# Single source of truth for ShapePipe's environment is the Dockerfile
# (slim Python + apt system deps + uv-frozen wheels). This workflow builds
# that image, runs the test suite *inside it* — so CI tests exactly what
# ships — and publishes to ghcr only on pushes to the integration branches.
#
# pull_request → build + test, no publish (also works for fork PRs)
# push → build + test + publish (:develop, :latest, …)
on:
push:
branches:
- develop
- main
- master
pull_request:
branches:
- develop
- main
- master
workflow_dispatch:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-test-publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
with:
driver-opts: network=host
# Two parallel tag sets. `dev` is the default (no suffix, e.g. `:latest`,
# `:develop`); `runtime` carries a `-runtime` suffix.
- name: Tags — dev (default)
id: meta-dev
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Tags — runtime
id: meta-runtime
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: |
suffix=-runtime,onlatest=true
# ----------------------------------------------------------------
# Build + test (every event)
# ----------------------------------------------------------------
# Build runtime first (smaller, used to smoke-test pipeline binaries)
- name: Build runtime (load)
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
target: runtime
load: true
tags: ${{ steps.meta-runtime.outputs.tags }}
labels: ${{ steps.meta-runtime.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# Smoke-test the binaries baked into the runtime image. Catches the
# class of regression where the image builds but a runtime tool
# (sextractor, weightwatcher) is missing or unrunnable.
- name: Test runtime — binaries
run: |
IMAGE=$(echo "${{ steps.meta-runtime.outputs.tags }}" | head -n1)
docker run --rm "$IMAGE" source-extractor --version
docker run --rm "$IMAGE" weightwatcher --version
docker run --rm "$IMAGE" psfex --version
- name: Test runtime — shapepipe entry point (read-only fs)
run: |
IMAGE=$(echo "${{ steps.meta-runtime.outputs.tags }}" | head -n1)
# --read-only + tmpfs /tmp emulates apptainer/SIF semantics: only
# /tmp is writable. shapepipe_run_example wraps shapepipe_run so
# the example tree gets copied into a mktemp workdir before running.
docker run --rm --read-only --tmpfs /tmp:rw "$IMAGE" shapepipe_run_example
# Build dev (reuses cached `base` layer)
- name: Build dev (load)
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
target: dev
load: true
tags: ${{ steps.meta-dev.outputs.tags }}
labels: ${{ steps.meta-dev.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# Verify the dev-only additions are present and runnable.
- name: Test dev — interactive tools
run: |
IMAGE=$(echo "${{ steps.meta-dev.outputs.tags }}" | head -n1)
docker run --rm "$IMAGE" vim --version | head -n1
docker run --rm "$IMAGE" rg --version | head -n1
# The actual test suite, run inside the shipped image — replacing the
# retired conda-based suite. pytest exercises the same wheels, binaries,
# and Python (3.12) that production runs on, not a parallel environment.
# pyproject's addopts add `--cov=shapepipe`; COVERAGE_FILE is set to /tmp
# in the image so it works on read-only filesystems too. The Hypothesis
# profile is explicit here so CI always uses the deterministic, capped
# property-test profile even if the default changes for local exploration.
- name: Test dev — pytest suite
run: |
IMAGE=$(echo "${{ steps.meta-dev.outputs.tags }}" | head -n1)
docker run --rm -e HYPOTHESIS_PROFILE=ci "$IMAGE" pytest -rX
# ----------------------------------------------------------------
# Publish (push events only — never on pull_request, incl. forks)
# ----------------------------------------------------------------
- name: Log in to the Container registry
if: github.event_name == 'push'
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Push runtime
if: github.event_name == 'push'
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
target: runtime
push: true
tags: ${{ steps.meta-runtime.outputs.tags }}
labels: ${{ steps.meta-runtime.outputs.labels }}
cache-from: type=gha
- name: Push dev
if: github.event_name == 'push'
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
target: dev
push: true
tags: ${{ steps.meta-dev.outputs.tags }}
labels: ${{ steps.meta-dev.outputs.labels }}
cache-from: type=gha