Skip to content

Commit fca6089

Browse files
authored
Merge pull request #4 from Daschi1/development
v1.4.0
2 parents 63d953a + e4d1e9d commit fca6089

9 files changed

Lines changed: 1194 additions & 954 deletions

File tree

.github/workflows/build-and-publish-docker-image.yml

Lines changed: 0 additions & 128 deletions
This file was deleted.
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
# GitHub Actions workflow: CI on PRs; Publish Docker image and Release on main
2+
name: CI and Publish (Docker + Release)
3+
4+
on:
5+
push:
6+
branches: [main] # Run CI and publish when commits land on main
7+
pull_request:
8+
branches: [main] # Run CI for PRs targeting main
9+
workflow_dispatch: # Allow manual runs from the Actions tab
10+
11+
# Least-privilege permissions required
12+
permissions:
13+
contents: write # needed to create GitHub releases (read is sufficient for checkout)
14+
packages: write # push images to GitHub Container Registry
15+
id-token: write # enable provenance/SLSA attestation by build-push-action
16+
17+
# Shared values
18+
env:
19+
REGISTRY: ghcr.io
20+
IMAGE_NAME: ${{ github.repository }} # e.g. owner/repo (may be mixed-case)
21+
22+
jobs:
23+
ci:
24+
name: CI (format, lint, check, gen:licenses, build)
25+
runs-on: ubuntu-latest
26+
steps:
27+
- name: Checkout
28+
uses: actions/checkout@v4
29+
30+
- name: Read tool versions from package.json
31+
id: tool-versions
32+
shell: bash
33+
run: |
34+
echo "::group::Read Node and pnpm versions from package.json"
35+
NODE_ENGINE=$(jq -r '.engines.node // ""' package.json)
36+
if [[ -z "$NODE_ENGINE" || "$NODE_ENGINE" == "null" ]]; then
37+
NODE_VERSION="22"
38+
else
39+
NODE_VERSION=$(echo "$NODE_ENGINE" | grep -oE '[0-9]+' | head -1)
40+
if [[ -z "$NODE_VERSION" ]]; then NODE_VERSION="22"; fi
41+
fi
42+
PM=$(jq -r '.packageManager // ""' package.json)
43+
if [[ -z "$PM" || "$PM" == "null" ]]; then
44+
PNPM_VERSION="10.15.0"
45+
else
46+
PNPM_VERSION=$(echo "$PM" | sed -n 's/^pnpm@\([0-9][^ ]*\).*$/\1/p')
47+
if [[ -z "$PNPM_VERSION" ]]; then PNPM_VERSION="10.15.0"; fi
48+
fi
49+
echo "Node engines: $NODE_ENGINE -> using $NODE_VERSION"
50+
echo "packageManager: $PM -> pnpm $PNPM_VERSION"
51+
echo "node=$NODE_VERSION" >> $GITHUB_OUTPUT
52+
echo "pnpm=$PNPM_VERSION" >> $GITHUB_OUTPUT
53+
echo "::endgroup::"
54+
55+
- name: Enable Corepack and pnpm
56+
shell: bash
57+
run: |
58+
echo "::group::Enable Corepack and prepare pnpm"
59+
corepack enable
60+
corepack prepare pnpm@${{ steps.tool-versions.outputs.pnpm }} --activate
61+
pnpm --version
62+
echo "::endgroup::"
63+
64+
- name: Configure pnpm store for actions cache
65+
shell: bash
66+
run: |
67+
echo "::group::Configure pnpm store path (~/.pnpm-store)"
68+
PNPM_STORE_DIR="$HOME/.pnpm-store"
69+
mkdir -p "$PNPM_STORE_DIR"
70+
pnpm config set store-dir "$PNPM_STORE_DIR"
71+
echo "pnpm store-dir => $(pnpm config get store-dir)"
72+
echo "::endgroup::"
73+
74+
- name: Set up Node.js
75+
uses: actions/setup-node@v4
76+
with:
77+
node-version: ${{ steps.tool-versions.outputs.node }}
78+
cache: "pnpm"
79+
cache-dependency-path: pnpm-lock.yaml
80+
81+
- name: Set up pnpm
82+
uses: pnpm/action-setup@v4
83+
with:
84+
version: ${{ steps.tool-versions.outputs.pnpm }}
85+
run_install: false
86+
87+
- name: Install dependencies
88+
shell: bash
89+
run: |
90+
echo "::group::pnpm install"
91+
pnpm --version
92+
pnpm install --frozen-lockfile
93+
echo "::endgroup::"
94+
95+
- name: Run format
96+
shell: bash
97+
run: |
98+
echo "::group::pnpm format"
99+
pnpm format
100+
echo "::endgroup::"
101+
102+
- name: Run lint
103+
shell: bash
104+
run: |
105+
echo "::group::pnpm lint"
106+
pnpm lint
107+
echo "::endgroup::"
108+
109+
- name: Run type check
110+
shell: bash
111+
run: |
112+
echo "::group::pnpm check"
113+
pnpm check
114+
echo "::endgroup::"
115+
116+
- name: Generate licenses
117+
shell: bash
118+
run: |
119+
echo "::group::pnpm gen:licenses"
120+
pnpm run gen:licenses
121+
echo "::endgroup::"
122+
123+
- name: Build app
124+
shell: bash
125+
run: |
126+
echo "::group::pnpm build"
127+
pnpm build
128+
echo "::endgroup::"
129+
130+
publish:
131+
name: Publish Docker image and GitHub Release
132+
needs: ci
133+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
134+
runs-on: ubuntu-latest
135+
steps:
136+
- name: Checkout
137+
uses: actions/checkout@v4
138+
139+
- name: Set up QEMU (for multi-arch builds)
140+
uses: docker/setup-qemu-action@v3
141+
142+
- name: Set up Docker Buildx
143+
uses: docker/setup-buildx-action@v3
144+
145+
- name: Log in to GHCR
146+
uses: docker/login-action@v3
147+
with:
148+
registry: ${{ env.REGISTRY }}
149+
username: ${{ github.actor }}
150+
password: ${{ secrets.GITHUB_TOKEN }} # auto-provided token with package:write
151+
152+
- name: Extract version from package.json
153+
id: version
154+
shell: bash
155+
run: |
156+
echo "::group::Read version from package.json"
157+
VERSION=$(jq -r .version package.json)
158+
echo "Detected version: ${VERSION}"
159+
if [[ -z "$VERSION" || "$VERSION" == "null" ]]; then
160+
echo "Could not read version from package.json" >&2
161+
echo "::endgroup::"
162+
exit 1
163+
fi
164+
IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION"
165+
echo "Parsed parts => MAJOR=${MAJOR}, MINOR=${MINOR}, PATCH=${PATCH}"
166+
echo "::endgroup::"
167+
echo "version=$VERSION" >> $GITHUB_OUTPUT
168+
echo "major=$MAJOR" >> $GITHUB_OUTPUT
169+
echo "minor=$MINOR" >> $GITHUB_OUTPUT
170+
echo "patch=$PATCH" >> $GITHUB_OUTPUT
171+
172+
- name: Compute tags
173+
id: meta
174+
shell: bash
175+
run: |
176+
echo "::group::Compute image reference and tags"
177+
IMAGE_NAME_LOWER=$(echo "${{ env.IMAGE_NAME }}" | tr '[:upper:]' '[:lower:]')
178+
IMAGE_REF=${{ env.REGISTRY }}/${IMAGE_NAME_LOWER}
179+
MAJOR=${{ steps.version.outputs.major }}
180+
MINOR=${{ steps.version.outputs.minor }}
181+
PATCH=${{ steps.version.outputs.patch }}
182+
VERSION=${{ steps.version.outputs.version }}
183+
184+
echo "Original IMAGE_NAME: ${{ env.IMAGE_NAME }}"
185+
echo "Normalized (lowercase) IMAGE_NAME: ${IMAGE_NAME_LOWER}"
186+
echo "Image reference: ${IMAGE_REF}"
187+
echo "Using version parts => MAJOR=${MAJOR}, MINOR=${MINOR}, PATCH=${PATCH}"
188+
189+
TAGS=(
190+
"${IMAGE_REF}:latest"
191+
"${IMAGE_REF}:${MAJOR}"
192+
"${IMAGE_REF}:${MAJOR}.${MINOR}"
193+
"${IMAGE_REF}:${VERSION}"
194+
)
195+
196+
echo "Planned tags:"
197+
for t in "${TAGS[@]}"; do echo " - ${t}"; done
198+
199+
TAGS_CSV=$(IFS=, ; echo "${TAGS[*]}")
200+
echo "tags=$TAGS_CSV" >> $GITHUB_OUTPUT
201+
echo "image_name_lower=${IMAGE_NAME_LOWER}" >> $GITHUB_OUTPUT
202+
echo "image_ref=${IMAGE_REF}" >> $GITHUB_OUTPUT
203+
echo "Computed tags CSV: ${TAGS_CSV}"
204+
echo "::endgroup::"
205+
206+
- name: Build and push
207+
uses: docker/build-push-action@v6
208+
with:
209+
context: .
210+
file: ./Dockerfile
211+
push: true
212+
provenance: true # generate provenance (SLSA) metadata
213+
sbom: true # generate SBOM and attach to the image
214+
tags: ${{ steps.meta.outputs.tags }}
215+
labels: |
216+
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
217+
org.opencontainers.image.revision=${{ github.sha }}
218+
org.opencontainers.image.version=${{ steps.version.outputs.version }}
219+
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ steps.meta.outputs.image_name_lower }}:buildcache
220+
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ steps.meta.outputs.image_name_lower }}:buildcache,mode=max
221+
222+
- name: Create GitHub Release
223+
uses: softprops/action-gh-release@v2
224+
with:
225+
tag_name: v${{ steps.version.outputs.version }}
226+
name: "${{ steps.version.outputs.version }} version"
227+
generate_release_notes: true
228+
229+
- name: Summarize publish details
230+
shell: bash
231+
run: |
232+
echo "## Docker Image Build Summary" >> "$GITHUB_STEP_SUMMARY"
233+
echo "Repository: ${{ env.REGISTRY }}/${{ steps.meta.outputs.image_name_lower }}" >> "$GITHUB_STEP_SUMMARY"
234+
echo "Version: ${{ steps.version.outputs.version }}" >> "$GITHUB_STEP_SUMMARY"
235+
echo "Action: Pushed the following tags:" >> "$GITHUB_STEP_SUMMARY"
236+
IFS=',' read -ra TAGS_ARR <<< "${{ steps.meta.outputs.tags }}"
237+
for t in "${TAGS_ARR[@]}"; do echo "- $t" >> "$GITHUB_STEP_SUMMARY"; done

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ COPY . .
1818

1919
# Install deps from store and build (postinstall will automatically generate licenses.json)
2020
RUN pnpm install --frozen-lockfile --offline \
21+
&& pnpm gen:licenses \
2122
&& pnpm build \
2223
&& pnpm prune --prod
2324

0 commit comments

Comments
 (0)