-
Notifications
You must be signed in to change notification settings - Fork 0
196 lines (171 loc) · 6.7 KB
/
Copy pathdocker-build-push.yml
File metadata and controls
196 lines (171 loc) · 6.7 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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
name: Build and Push Docker Image (GHCR + Docker Hub)
on:
push:
branches: [ main ]
tags:
- 'v*'
paths:
- 'src/**'
- 'Cargo.toml'
- 'Cargo.lock'
- 'Dockerfile'
- '.dockerignore'
- '.github/workflows/docker-build-push.yml'
pull_request:
branches: [ main ]
paths:
- 'src/**'
- 'Cargo.toml'
- 'Cargo.lock'
- 'Dockerfile'
- '.dockerignore'
workflow_dispatch:
env:
GHCR_IMAGE: ghcr.io/clutchprotocol/clutch-node
DH_IMAGE: docker.io/9194010019/clutch-node
permissions:
contents: read
packages: write
jobs:
# One job per architecture on a NATIVE runner. arm64 used to be cross-built with
# QEMU on ubuntu-latest, which emulates every instruction — rocksdb's C++ compile
# alone ran 5-10x slower there. GitHub-hosted arm64 runners are free for public
# repos, so both arches now compile natively and in parallel.
build:
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
steps:
- name: Platform slug (linux/amd64 -> linux-amd64)
run: echo "SLUG=${{ matrix.platform }}" | tr '/' '-' >> "$GITHUB_ENV"
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Cache lives in GHCR, not type=gha. The Actions cache backend caps at 10 GB
# per repo; mode=max on a Rust build (deps target dir, x2 arches) blew past
# that every run, so the dependency layer was evicted and rocksdb rebuilt from
# scratch. A registry cache has no such cap. One cache tag per arch — a shared
# tag makes the two runners overwrite each other's manifest.
#
# Pushed by digest only; the `merge` job assembles the tagged manifest lists.
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
platforms: ${{ matrix.platform }}
provenance: false
cache-from: type=registry,ref=${{ env.GHCR_IMAGE }}:buildcache-${{ env.SLUG }}
# ignore-error: cache export intermittently fails after a successful push
# (seen 2026-07-24, run 30084470164) — that must not fail the job, since
# trigger-stage-deploy needs this and a failed export would block deploys.
cache-to: ${{ github.event_name != 'pull_request' && format('type=registry,ref={0}:buildcache-{1},mode=max,ignore-error=true', env.GHCR_IMAGE, env.SLUG) || '' }}
# Empty on PRs: build-only verification, no output, no registry writes.
outputs: ${{ github.event_name != 'pull_request' && format('type=image,name={0},push-by-digest=true,name-canonical=true,push=true', env.GHCR_IMAGE) || '' }}
- name: Export digest
if: github.event_name != 'pull_request'
run: |
mkdir -p /tmp/digests
digest='${{ steps.build.outputs.digest }}'
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.SLUG }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
# Assemble the multi-arch manifest from the per-arch digests. No rebuild happens
# here — imagetools copies manifests/blobs, including cross-registry to Docker Hub.
merge:
needs: build
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.GHCR_IMAGE }}
${{ env.DH_IMAGE }}
tags: |
# sha-<short>
type=sha,format=short
# latest فقط روی برنچ پیشفرض (main)
type=raw,value=latest,enable={{is_default_branch}}
# اگر تگ گیت (v1.2.3) داشتی همون رو tag کن
type=ref,event=tag
- name: Create manifest lists on both registries
working-directory: /tmp/digests
run: |
# shellcheck disable=SC2046 # word splitting is the point: expands to
# `-t img:tag -t img:tag ...` and one `img@sha256:...` per digest file.
docker buildx imagetools create \
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.GHCR_IMAGE }}@sha256:%s ' *)
- name: Image digest
run: docker buildx imagetools inspect ${{ env.GHCR_IMAGE }}:${{ steps.meta.outputs.version }}
# Optional: same secret as other Clutch repos — PAT with repo access to dispatch on clutch-deploy.
trigger-stage-deploy:
needs: merge
runs-on: ubuntu-latest
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
steps:
- name: Trigger deploy-stage in clutch-deploy
continue-on-error: true
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.CLUTCH_DEPLOY_DISPATCH_TOKEN }}
repository: clutchprotocol/clutch-deploy
event-type: deploy-stage
update-description:
needs: merge
runs-on: ubuntu-latest
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Update Docker Hub description
uses: peter-evans/dockerhub-description@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: 9194010019/clutch-node
readme-filepath: ./README.md