Skip to content

Commit 7d8003d

Browse files
authored
fix: switch to pnpm, harden docker, harden GitHub release (#158)
1 parent 4753205 commit 7d8003d

14 files changed

Lines changed: 6810 additions & 10137 deletions

File tree

.dockerignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
*
22
!nest-cli.json
33
!src/
4-
!package-lock.json
4+
!pnpm-lock.yaml
5+
!pnpm-workspace.yaml
56
!package.json
67
!tsconfig.build.json
78
!tsconfig.json
8-
!entrypoint.sh
9+
!entrypoint.prod.sh
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Setup pnpm + Node
2+
description: Activate Node + pnpm via corepack, restore the pnpm store cache, and run a frozen-lockfile install.
3+
4+
runs:
5+
using: composite
6+
steps:
7+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
8+
with:
9+
node-version: '24'
10+
11+
- shell: bash
12+
run: |
13+
corepack enable
14+
corepack prepare pnpm@10.33.4 --activate
15+
16+
- uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
17+
with:
18+
path: ~/.local/share/pnpm/store
19+
key: pnpm-store-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
20+
restore-keys: |
21+
pnpm-store-${{ runner.os }}-
22+
23+
- shell: bash
24+
run: pnpm install --frozen-lockfile

.github/dependabot.yml

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,69 @@
1-
# To get started with Dependabot version updates, you'll need to specify which
2-
# package ecosystems to update and where the package manifests are located.
3-
# Please see the documentation for all configuration options:
4-
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
1+
# Dependabot config.
2+
# Reference: https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference
3+
# The "npm" ecosystem covers pnpm (Dependabot reads pnpm-lock.yaml).
54

65
version: 2
76
updates:
8-
- package-ecosystem: "npm" # See documentation for possible values
9-
directory: "/" # Location of package manifests
7+
- package-ecosystem: "npm"
8+
directory: "/"
109
schedule:
1110
interval: "weekly"
11+
day: "monday"
12+
time: "08:00"
13+
timezone: "Europe/Berlin"
14+
open-pull-requests-limit: 15
15+
labels:
16+
- "dependencies"
17+
- "npm"
18+
commit-message:
19+
prefix: "chore(deps)"
20+
prefix-development: "chore(deps-dev)"
21+
include: "scope"
22+
# 7-day cooldown mirrors pnpm-workspace.yaml minimumReleaseAge: 10080.
23+
# Security updates ignore cooldown (Dependabot rule).
24+
cooldown:
25+
default-days: 7
1226
groups:
13-
all-minor-patch-updates:
14-
patterns:
15-
- "*"
16-
update-types:
17-
- "minor"
18-
- "patch"
19-
open-pull-requests-limit: 20
20-
- package-ecosystem: "docker" # See documentation for possible values
21-
directory: "/" # Location of package manifests
27+
production-dependencies:
28+
dependency-type: "production"
29+
update-types: ["minor", "patch"]
30+
development-dependencies:
31+
dependency-type: "development"
32+
update-types: ["minor", "patch"]
33+
34+
- package-ecosystem: "docker"
35+
directory: "/"
2236
schedule:
2337
interval: "weekly"
24-
- package-ecosystem: "github-actions" # See documentation for possible values
25-
directory: "/" # Location of package manifests
38+
day: "monday"
39+
time: "08:00"
40+
timezone: "Europe/Berlin"
41+
open-pull-requests-limit: 5
42+
labels:
43+
- "dependencies"
44+
- "docker"
45+
commit-message:
46+
prefix: "chore(docker)"
47+
include: "scope"
48+
cooldown:
49+
default-days: 7
50+
# Node base image is bumped manually on the Node LTS cycle.
51+
ignore:
52+
- dependency-name: "node"
53+
54+
- package-ecosystem: "github-actions"
55+
directory: "/"
2656
schedule:
27-
interval: "monthly"
57+
interval: "weekly"
58+
day: "monday"
59+
time: "08:00"
60+
timezone: "Europe/Berlin"
61+
open-pull-requests-limit: 5
62+
labels:
63+
- "dependencies"
64+
- "github-actions"
65+
commit-message:
66+
prefix: "chore(actions)"
67+
include: "scope"
68+
cooldown:
69+
default-days: 7

.github/workflows/ci.yml

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
name: Docker Image CI
1+
name: CI
2+
23
permissions:
34
contents: read
45

@@ -15,64 +16,63 @@ jobs:
1516
runs-on: ubuntu-latest
1617

1718
steps:
18-
- uses: actions/checkout@v6
19-
20-
- name: Set up QEMU
21-
uses: docker/setup-qemu-action@v3
19+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
2220

2321
- name: Set up Docker Buildx
24-
uses: docker/setup-buildx-action@v3
22+
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
2523

26-
- name: Login to GitHub Container Registry
27-
uses: docker/login-action@v3
28-
with:
29-
registry: ghcr.io
30-
username: ${{ github.repository_owner }}
31-
password: ${{ secrets.GITHUB_TOKEN }}
32-
33-
- uses: actions/setup-node@v6
34-
with:
35-
node-version: '24'
36-
- name: Build and export to Docker
37-
uses: docker/build-push-action@v6
24+
- name: Build Docker image (smoke test)
25+
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
3826
with:
3927
context: .
28+
target: production
4029
tags: |
4130
ghcr.io/kitsteam/excalidraw-storage-backend:latest
31+
cache-from: type=gha
32+
cache-to: type=gha,mode=max
4233

4334
excalidraw-storage-backend-nest-build:
4435
runs-on: ubuntu-latest
4536

4637
steps:
47-
- uses: actions/checkout@v6
38+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
39+
- uses: ./.github/actions/setup-pnpm
40+
- run: pnpm run build
4841

49-
- uses: actions/setup-node@v6
50-
with:
51-
node-version: '24'
42+
excalidraw-storage-backend-format:
43+
runs-on: ubuntu-latest
5244

53-
- run: npm i
54-
- run: npm run build
45+
steps:
46+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
47+
- uses: ./.github/actions/setup-pnpm
48+
- run: pnpm run format:check
5549

56-
excalidraw-storage-backend-format:
50+
excalidraw-storage-backend-test:
5751
runs-on: ubuntu-latest
5852

5953
steps:
60-
- uses: actions/checkout@v6
54+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
55+
- uses: ./.github/actions/setup-pnpm
56+
- run: pnpm run test
6157

62-
- uses: actions/setup-node@v6
63-
with:
64-
node-version: '24'
58+
excalidraw-storage-backend-audit:
59+
runs-on: ubuntu-latest
6560

66-
- run: npm i
67-
- run: npm run format:check
61+
steps:
62+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
63+
- uses: ./.github/actions/setup-pnpm
64+
- name: pnpm audit (fail on high/critical production deps)
65+
run: pnpm audit --audit-level=high --prod
6866

69-
excalidraw-storage-backend-test:
67+
dependency-review:
7068
runs-on: ubuntu-latest
69+
if: github.event_name == 'pull_request'
70+
7171
steps:
72-
- uses: actions/checkout@v6
73-
- uses: actions/setup-node@v6
74-
with:
75-
node-version: '24'
72+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
7673

77-
- run: npm i
78-
- run: npm run test
74+
- name: Dependency Review (PR diff vs base)
75+
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
76+
with:
77+
fail-on-severity: high
78+
allow-licenses: MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, 0BSD, CC0-1.0, Unlicense, BlueOak-1.0.0, Zlib, CC-BY-4.0

.github/workflows/release.yml

Lines changed: 95 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,129 @@
11
# https://docs.github.com/en/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#upgrading-a-workflow-that-accesses-ghcrio
22

3-
# This workflow uses actions that are not certified by GitHub.
4-
# They are provided by a third-party and are governed by
5-
# separate terms of service, privacy policy, and support
6-
# documentation.
7-
8-
# GitHub recommends pinning actions to a commit SHA.
9-
# To get a newer version, you will need to update the SHA.
10-
# You can also reference a tag or branch, but the action may change without warning.
3+
# Third-party actions are pinned to a full commit SHA (with the human-readable
4+
# version in a trailing comment) to protect against tag-rewrite supply-chain
5+
# attacks. To bump a version, update both the SHA and the comment.
116

127
name: Create and publish a Docker image
138

149
on:
1510
release:
1611
types: [published]
17-
push:
18-
branches:
19-
- main
12+
13+
concurrency:
14+
group: ${{ github.workflow }}-${{ github.ref }}
15+
cancel-in-progress: false
2016

2117
env:
2218
REGISTRY: ghcr.io
2319
IMAGE_NAME: ${{ github.repository }}
2420

2521
jobs:
26-
build-and-push-image:
27-
runs-on: ubuntu-latest
22+
build:
23+
runs-on: ${{ matrix.runner }}
2824
permissions:
2925
contents: read
3026
packages: write
27+
strategy:
28+
fail-fast: false
29+
matrix:
30+
include:
31+
- platform: linux/amd64
32+
runner: ubuntu-latest
33+
suffix: amd64
34+
- platform: linux/arm64
35+
runner: ubuntu-24.04-arm
36+
suffix: arm64
3137

3238
steps:
3339
- name: Checkout repository
34-
uses: actions/checkout@v5
40+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
41+
42+
- name: Set up Docker Buildx
43+
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
44+
3545
- name: Log in to the Container registry
36-
uses: docker/login-action@v3
46+
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4
3747
with:
3848
registry: ${{ env.REGISTRY }}
3949
username: ${{ github.actor }}
4050
password: ${{ secrets.GITHUB_TOKEN }}
4151

4252
- name: Extract metadata (tags, labels) for Docker
4353
id: meta
44-
uses: docker/metadata-action@v5
54+
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6
4555
with:
4656
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
4757

48-
- name: Build and push Docker image
49-
uses: docker/build-push-action@v6
58+
- name: Build and push Docker image by digest
59+
id: build
60+
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
5061
with:
62+
platforms: ${{ matrix.platform }}
5163
target: production
52-
push: true
53-
tags: ${{ steps.meta.outputs.tags }}
5464
labels: ${{ steps.meta.outputs.labels }}
65+
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
66+
cache-from: type=gha,scope=${{ matrix.suffix }}
67+
cache-to: type=gha,scope=${{ matrix.suffix }},mode=max
68+
69+
- name: Export digest
70+
env:
71+
DIGEST: ${{ steps.build.outputs.digest }}
72+
run: |
73+
mkdir -p /tmp/digests
74+
touch "/tmp/digests/${DIGEST#sha256:}"
75+
76+
- name: Upload digest artifact
77+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
78+
with:
79+
name: digests-${{ matrix.suffix }}
80+
path: /tmp/digests/*
81+
if-no-files-found: error
82+
retention-days: 1
83+
84+
merge:
85+
runs-on: ubuntu-latest
86+
needs: build
87+
permissions:
88+
contents: read
89+
packages: write
90+
91+
steps:
92+
- name: Download digests
93+
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
94+
with:
95+
path: /tmp/digests
96+
pattern: digests-*
97+
merge-multiple: true
98+
99+
- name: Set up Docker Buildx
100+
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
101+
102+
- name: Log in to the Container registry
103+
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4
104+
with:
105+
registry: ${{ env.REGISTRY }}
106+
username: ${{ github.actor }}
107+
password: ${{ secrets.GITHUB_TOKEN }}
108+
109+
- name: Extract metadata (tags, labels) for Docker
110+
id: meta
111+
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6
112+
with:
113+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
114+
115+
- name: Create and push multi-arch manifest
116+
working-directory: /tmp/digests
117+
env:
118+
IMAGE_REF: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
119+
run: |
120+
docker buildx imagetools create \
121+
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
122+
$(printf "${IMAGE_REF}@sha256:%s " *)
123+
124+
- name: Inspect image
125+
env:
126+
IMAGE_REF: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
127+
VERSION: ${{ steps.meta.outputs.version }}
128+
run: |
129+
docker buildx imagetools inspect "${IMAGE_REF}:${VERSION}"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# compiled output
22
/dist
33
/node_modules
4+
/.pnpm-store
45

56
# Logs
67
logs

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
save-exact=true

0 commit comments

Comments
 (0)