-
Notifications
You must be signed in to change notification settings - Fork 0
266 lines (233 loc) Β· 8.28 KB
/
build.yaml
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
name: ποΈ Build
# Trigger this workflow when changes happen to our core directories
on:
push:
paths:
- "engine/**" # Our Rust backend
- "web/**" # Our web frontend
- ".github/workflows/build.yaml"
# Set up some global variables we'll use throughout
env:
REGISTRY: ghcr.io
IMAGE_NAME: v3xlabs/v3x-property/engine
BINARY_NAME: v3x-property-engine
DOCKER_BUILDKIT: 1 # Enable BuildKit
COMPOSE_DOCKER_CLI_BUILD: 1
jobs:
# π¦ First job: Build our Rust backend for multiple architectures
build-engine:
strategy:
matrix:
platform:
- arch: x86_64-unknown-linux-musl
docker: linux/amd64
- arch: aarch64-unknown-linux-musl
docker: linux/arm64
timeout-minutes: 20 # Prevent hanging builds
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
# Set up Rust with the specific target we need
- name: Install Rust
run: rustup toolchain install stable --profile minimal --no-self-update
# Speed up builds by caching dependencies
- name: Cache Rust
uses: Swatinem/rust-cache@v2
with:
workspaces: engine
key: ${{ matrix.platform.arch }}
# Install cross
- name: Install cross
run: cargo install cross
# Update version number in engine/Cargo.toml
# If tag is a release use that
# Otherwise use the version number in the engine/Cargo.toml and append it with -alpha
- name: Update version number
run: |
if [[ "${{ github.ref }}" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
VERSION=${GITHUB_REF#refs/tags/v}
echo "Release tag detected, using version: $VERSION"
sed -i "0,/^version = .*/s//version = \"${VERSION}\"/" engine/Cargo.toml
else
echo "No release tag detected, using version from Cargo.toml"
# parse version from Cargo.toml using regex
version=$(grep -oP 'version = "([^"]+?)"' engine/Cargo.toml | head -n 1 | sed 's/^version = "\(.*\)"$/\1/')
echo "Current version: $version"
sed -i '0,/^version = .*/s//version = "'${version}'-alpha"/' engine/Cargo.toml
fi
# π¨ Build our static binary
- name: Build Rust binary
working-directory: ./engine
env:
BINARY_NAME: ${{ env.BINARY_NAME }}
SQLX_OFFLINE: true # Use prepared SQL queries
run: cross build --target ${{ matrix.platform.arch }} --release
# π¦ Save our binary for later
- name: Upload built binary as artifact
uses: actions/upload-artifact@v4
with:
name: engine-${{ matrix.platform.arch }}
path: engine/target/${{ matrix.platform.arch }}/release/${{ env.BINARY_NAME }}
retention-days: 1 # Save storage by cleaning up quickly
compression-level: 9 # Maximum compression
# π Second job: Build our web frontend
build-web:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
# Get our Node.js tools ready
- name: Install Tools & Dependencies
uses: ./.github/actions/install
# Build the web assets
- name: Build
working-directory: ./web
run: NODE_ENV=production pnpm run build
# π¦ Save our web assets for later
- name: Upload built web as artifact
uses: actions/upload-artifact@v4
with:
name: web
path: web/dist
# π³ Third job: Package everything into a multi-arch Docker digests
docker-build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
needs: # Wait for other jobs to finish
- build-engine
- build-web
strategy:
matrix:
platform:
- arch: x86_64-unknown-linux-musl
docker: linux/amd64
- arch: aarch64-unknown-linux-musl
docker: linux/arm64
steps:
- name: Checkout
uses: actions/checkout@v4
# π₯ Grab our built binary
- name: Download built binary
uses: actions/download-artifact@v4
id: engine-binary
with:
name: engine-${{ matrix.platform.arch }}
path: artifacts
# π₯ Grab our web assets
- name: Download built web
uses: actions/download-artifact@v4
id: web
with:
name: web
path: artifacts/web
- name: Prepare artifacts
run: |
chmod 755 ./artifacts/v3x-property-engine
ls -la ./artifacts
# Set up QEMU for multi-arch builds
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
# Set up Docker Buildx
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Log into GitHub's container registry
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Extract metadata
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# π Build and push multi-arch Docker image
- name: Build Docker digests
uses: docker/build-push-action@v6
id: build
with:
context: ./artifacts
file: ./engine/.build/Dockerfile.scratch
platforms: ${{ matrix.platform.docker }}
labels: ${{ steps.meta.outputs.labels }}
annotations: ${{ steps.meta.outputs.annotations }}
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
build-args: |
BINARY_PATH=./v3x-property-engine
WEBUI_PATH=./web
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ matrix.platform.arch }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
# π³ Final job: Merge multi-arch digests into a single artifact
docker-merge:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')
permissions:
contents: read
packages: write
attestations: write # For security attestations
id-token: write
needs: # Wait for other jobs to finish
- docker-build
steps:
- name: Checkout
uses: actions/checkout@v4
# π₯ Grab our digests
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
# Log into GitHub's container registry
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Set up Docker Buildx
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Extract metadata
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=edge
type=sha
- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
- name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}