Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 26 additions & 18 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,26 @@ jobs:
destination: "/"
storageZoneName: ${{ secrets.BUNNY_STORAGE_ZONE_NAME }}
storagePassword: ${{ secrets.BUNNY_STORAGE_PASSWORD }}
accessKey: ${{ secrets.BUNNY_API_KEY }}
accessKey: ${{ secrets.BUNNYNET_API_KEY }}
pullZoneId: ${{ secrets.BUNNY_PULL_ZONE_ID }}
upload: "true"
remove: "true"
purgePullZone: "true"

# Admin Docker build/push/roll. Skipped for md/pen-only changes via
# paths-filter — note the leading '**' positive pattern: paths-filter
# treats negation-only filters as never matching.
# Admin Docker build/push to ghcr.io + Magic Container roll. Follows
# bunny.net's canonical pattern (see
# https://docs.bunny.net/magic-containers/deploy-with-github-actions.md):
# ghcr.io for image hosting (no extra credentials — GITHUB_TOKEN does it),
# BunnyWay/actions/container-update-image to roll the container.
# Gated on vars.APP_ID so the job is skipped before the admin Magic
# Container app exists.
build-admin:
needs: verify
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && vars.APP_ID != ''
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4

Expand All @@ -108,13 +115,13 @@ jobs:
if: steps.changes.outputs.app == 'true'
uses: docker/setup-buildx-action@v3

- name: Log in to bunny.net container registry
- name: Log in to GitHub Container Registry
if: steps.changes.outputs.app == 'true'
uses: docker/login-action@v3
with:
registry: ${{ secrets.BUNNY_REGISTRY }}
username: ${{ secrets.BUNNY_REGISTRY_USERNAME }}
password: ${{ secrets.BUNNY_REGISTRY_PASSWORD }}
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push admin image
if: steps.changes.outputs.app == 'true'
Expand All @@ -123,14 +130,15 @@ jobs:
context: .
file: apps/admin/Dockerfile
push: true
tags: ${{ secrets.BUNNY_REGISTRY }}/${{ vars.ADMIN_APP_ID }}:${{ github.sha }},${{ secrets.BUNNY_REGISTRY }}/${{ vars.ADMIN_APP_ID }}:latest
tags: |
ghcr.io/${{ github.repository_owner }}/wardrobe-assistants-admin:${{ github.sha }}
ghcr.io/${{ github.repository_owner }}/wardrobe-assistants-admin:latest

- name: Roll Magic Container deployment
- name: Roll admin Magic Container to new image
if: steps.changes.outputs.app == 'true'
env:
BUNNY_API_KEY: ${{ secrets.BUNNY_API_KEY }}
ADMIN_APP_ID: ${{ vars.ADMIN_APP_ID }}
run: |
curl -fsS -X POST \
-H "AccessKey: $BUNNY_API_KEY" \
"https://api.bunny.net/magic-containers/apps/$ADMIN_APP_ID/deploy"
uses: BunnyWay/actions/container-update-image@main
with:
app_id: ${{ vars.APP_ID }}
api_key: ${{ secrets.BUNNYNET_API_KEY }}
container: wardrobe-assistants-admin
image_tag: ${{ github.sha }}
Comment on lines +137 to +144

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

GitHub Actions security hardening pin third-party action commit SHA

💡 Result:

To harden GitHub Actions security, especially for third-party actions, pin them to a full-length (40-character) commit SHA instead of mutable tags or branches. This prevents supply chain attacks where tags are rewritten or repositories compromised to inject malicious code, as SHAs are immutable [1][2][3]. Example workflow change: Before: uses: some/action@v1 After: uses: some/action@692973e3d937129bcbf40652eb9f2f61becf3332 # v1.0.0 [1][3][4] How to find the SHA [3]: 1. Go to the action's repo (e.g., https://github.com/owner/repo for owner/repo). 2. Switch to the tag/branch (e.g., v1). 3. Copy the full commit SHA from the commit page. Or run: git ls-remote --tags https://github.com/owner/repo.git v1 [4]. Or check a workflow run log under "Set up job" for the resolved SHA [3]. Add a comment with the version for reference [5][4][6]. Use Dependabot to update pinned SHAs automatically [1]. Enforce via policies: At repo/org/enterprise level, enable "Require full commit SHA for actions" in Actions settings > General > Policies. Unpinned workflows fail [2][7]. Prefer verified creators from Marketplace [1]. Tools like GitHub Actions Lockfile can generate/verify lockfiles with SHAs [8].

Citations:


🌐 Web query:

BunnyWay/actions container-update-image action GitHub repository

💡 Result:

The BunnyWay/actions/container-update-image is a GitHub Action within the BunnyWay/actions repository [1]. It updates container images for Bunny.net's Magic Containers platform, automating rolling updates after building and pushing new Docker images [2][3]. Repository details: https://github.com/BunnyWay/actions (created 2024-08-09, last push 2026-03-27, 13 stars, JavaScript primary language) [1]. The action is in the container-update-image folder, with its own documentation there [1]. Latest release: container-update-image_0.2.1 (2026-03-27) [1][4]. Usage example from official Bunny.net docs [2]: - name: Update container image on Magic Containers uses: BunnyWay/actions/container-update-image@main with: app_id: ${{ vars.APP_ID }} api_key: ${{ secrets.BUNNYNET_API_KEY }} container: app image_tag: "${{ github.sha }}" Required inputs [2]: - app_id: Magic Containers App ID - api_key: Bunny.net API key (no sub-user support) - container: Container name - image_tag: New image tag Recent updates include support for optional image_digest [5], removing imageDigest when updating imageTag [4], Node.js 20 (issue open for upgrade to 24) [6]. It's used in workflows for Magic Containers deployments [7].

Citations:


🌐 Web query:

GitHub Actions Node.js 20 deprecated June 2026 timeline

💡 Result:

GitHub Actions is deprecating Node.js 20 support on hosted runners. Starting June 2nd, 2026, runners will default to Node.js 24 for JavaScript actions.[1][2] Users can opt out temporarily by setting ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true in their workflow or runner environment, but Node 20 will be fully removed later in fall 2026.[1] Node.js 20 reaches upstream EOL on April 30, 2026.[3] Warnings already appear for actions using Node 20, like actions/checkout@v4.[4] Newer runner versions (e.g., v2.328.0+) support both Node 20 and 24, defaulting to 20 currently.[1] To test Node 24 early, set FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true.[1] Action maintainers should update to Node 24 (via actions configuration).[1] Users should pin latest action versions supporting Node 24. setup-node@v4+ supports Node 22/24.[5] ubuntu-latest (ubuntu-24.04) currently defaults to Node 20.x, discussions ongoing to update post-EOL.[3]

Citations:


🌐 Web query:

GitHub Actions node20 runtime deprecation schedule

💡 Result:

GitHub Actions Node 20 runtime deprecation schedule, as of today's date (2026-05-05): Node.js 20 reaches end-of-life (EOL) on 2026-04-30 [1][2]. Deprecation process started due to EOL. Runners currently default to Node 20 but support Node 24 [1]. Key dates: - Beginning June 2, 2026: Runners will use Node 24 by default for JavaScript actions. Workflows can opt out to continue using Node 20 by setting ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true env var (until full removal) [1][3]. - Later in fall 2026 (around September/October): Node 20 fully removed from runners [1][4]. Editor's note on the changelog updated February 25, 2026, confirms migration to June 2026 [1]. To test Node 24 early: Set FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true [1]. Action maintainers should update actions.yml to 'node24' [1]. Ubuntu-latest currently defaults to Node 20.20.2, discussions ongoing to update post-EOL, ideally aligning with June 2 [2].

Citations:


Pin BunnyWay/actions/container-update-image to a commit SHA instead of @main.

@main is a moving reference: any push to that branch (including a compromised one) immediately runs in your release pipeline with access to secrets.BUNNYNET_API_KEY and the ability to roll the production Magic Container. GitHub's hardening guide and OpenSSF Scorecard both recommend pinning third-party actions to a full 40-character commit SHA. You can leave a # v… comment alongside for readability, and Dependabot can still bump the SHA on its schedule.

A secondary concern: per BunnyWay/actions#25, container-update-image currently declares using: 'node20'. GitHub is forcing Node.js 20 to Node.js 24 starting June 2, 2026 (Node.js 20 reaches EOL April 30, 2026). Pinning to a specific SHA makes that future breakage visible and controllable rather than a surprise mid-deploy.

🔒 Suggested change
-        uses: BunnyWay/actions/container-update-image@main
+        # pin: replace <sha> with the full commit SHA of the desired version
+        uses: BunnyWay/actions/container-update-image@<sha>  # main as of YYYY-MM-DD
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/deploy.yml around lines 137 - 144, The workflow uses the
third-party action reference BunnyWay/actions/container-update-image@main which
is a moving ref and gives deploy-time access to secrets
(secrets.BUNNYNET_API_KEY) — replace the `@main` tag with the full 40-character
commit SHA for BunnyWay/actions/container-update-image to pin the exact code
used when updating the wardrobe-assistants-admin container (container:
wardrobe-assistants-admin, image_tag: ${{ github.sha }}); add a short comment
like “# vX.Y.Z” for readability and update the SHA via Dependabot or PRs, and
confirm the pinned commit is compatible with future Node.js runtime changes
referenced in BunnyWay/actions#25.

8 changes: 8 additions & 0 deletions apps/admin/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ WORKDIR /repo
COPY --from=deps /repo/node_modules ./node_modules
COPY --from=deps /repo/apps/admin/node_modules ./apps/admin/node_modules
COPY . .
# Placeholder env for Next's build-time page-data collection. Runtime
# values come from the container env, not from this image — these never
# leak into the runner stage because ENV doesn't cross FROM boundaries.
ENV DATABASE_URL=file:./build.db \
BETTER_AUTH_SECRET=build-placeholder-secret-not-used-at-runtime-32b \
BETTER_AUTH_URL=https://admin.wardrobe-assistants.ch \
RESEND_API_KEY=build-placeholder \
EMAIL_FROM=admin@wardrobe-assistants.ch
RUN npm -w apps/admin run build

FROM node:22-alpine AS runner
Expand Down
Loading