Repository navigation
160 lines (141 loc) · 6.39 KB
/
Copy pathrelease-web.yml
File metadata and controls
160 lines (141 loc) · 6.39 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
name: Release Web
on:
release:
types: [released, prereleased]
workflow_dispatch:
inputs:
ref:
description: "Git ref (branch, tag, or SHA) to build"
required: false
default: ""
tag_name:
description: "Tag to use for artifacts/images (defaults to <sha>)"
required: false
default: ""
attach_to_release:
description: "Upload build.tar to an existing GitHub Release (requires tag_name)"
required: false
type: boolean
default: false
permissions:
contents: write
packages: write
env:
REGISTRY_IMAGE: ghcr.io/${{ github.repository }}
jobs:
release-web:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
ref: ${{ inputs.ref != '' && inputs.ref || github.ref }}
- name: Setup pnpm
uses: pnpm/action-setup@v6
- name: Setup Node.js
uses: actions/setup-node@v7
with:
# Pinned here, not read from .nvmrc: inputs.ref can check out a
# revision from before .nvmrc existed. Keep in sync with .nvmrc.
node-version: 24
cache: pnpm
cache-dependency-path: "**/pnpm-lock.yaml"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build web package
working-directory: apps/web
run: pnpm run build
- name: Create release archive
working-directory: apps/web
run: pnpm run package
- name: Upload archive (artifact)
uses: actions/upload-artifact@v7
with:
name: web-build
path: apps/web/dist/build.tar
if-no-files-found: error
- name: Attach archive to GitHub Release
if: ${{ github.event_name == 'release' || inputs.attach_to_release == true }}
uses: softprops/action-gh-release@v3
with:
files: apps/web/dist/build.tar
tag_name: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.tag_name }}
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Compute created timestamp & short SHA for labels/tags
- name: Compute meta
id: gen
shell: bash
run: |
echo "created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"
echo "shortsha=$(git rev-parse --short=12 HEAD)" >> "$GITHUB_OUTPUT"
# Build/tag matrix:
# - For release events: vX.Y.Z, semver helpers, and latest (only if NOT prerelease)
# - For prerelease events: vX.Y.Z and semver helpers (NO latest)
# - For manual runs:
# * if tag_name set: that raw tag
# * else: adhoc-<shortsha>
- name: Docker metadata (tags & labels)
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.REGISTRY_IMAGE }}
labels: |
org.opencontainers.image.source=${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.created=${{ steps.gen.outputs.created }}
tags: |
# Full release (semantic tag)
type=raw,value=${{ github.event.release.tag_name }},enable=${{ github.event_name == 'release' }}
# Semver helpers (major, major.minor) for releases/prereleases
type=semver,pattern={{version}},value=${{ github.event.release.tag_name }},enable=${{ github.event_name == 'release' }}
type=semver,pattern={{major}}.{{minor}},value=${{ github.event.release.tag_name }},enable=${{ github.event_name == 'release' && github.event.release.prerelease == false }}
type=semver,pattern={{major}},value=${{ github.event.release.tag_name }},enable=${{ github.event_name == 'release' && github.event.release.prerelease == false }}
# Latest only for full releases (not prereleases)
type=raw,value=latest,enable=${{ github.event_name == 'release' && github.event.release.prerelease == false }}
# Manual: provided tag_name
type=raw,value=${{ inputs.tag_name }},enable=${{ github.event_name == 'workflow_dispatch' && inputs.tag_name != '' }}
# Manual: fallback to adhoc-<shortsha>
type=raw,value=adhoc-${{ steps.gen.outputs.shortsha }},enable=${{ github.event_name == 'workflow_dispatch' && inputs.tag_name == '' }}
# Always add immutable sha tag for traceability
type=raw,value=sha-${{ steps.gen.outputs.shortsha }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Buildx
uses: docker/setup-buildx-action@v4
- name: Login to GHCR
uses: docker/login-action@v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Push images for:
# - release (released or prereleased)
# - manual with a tag_name (adhoc builds can still be pushed by name)
- name: Build and push image
uses: docker/build-push-action@v7
with:
context: .
file: ./apps/web/infra/Containerfile
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.tag_name != '') }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
provenance: false
- name: Output image refs
if: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.tag_name != '') }}
run: |
echo "🖼️ Pushed tags:"
echo "${{ steps.meta.outputs.tags }}"
echo
echo "Pull examples:"
if [[ "${{ github.event_name }}" == "release" && "${{ github.event.release.prerelease }}" == "false" ]]; then
echo " docker pull ${{ env.REGISTRY_IMAGE }}:latest"
fi
# Always available:
echo " docker pull ${{ env.REGISTRY_IMAGE }}:${{ github.event.release.tag_name || inputs.tag_name || format('adhoc-{0}', steps.gen.outputs.shortsha) }}"
echo " docker pull ${{ env.REGISTRY_IMAGE }}:sha-${{ steps.gen.outputs.shortsha }}"
- name: Explain no image push
if: ${{ !(github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.tag_name != '')) }}
run: echo "ℹ️ No image pushed (manual run without tag_name)."