Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
26 changes: 18 additions & 8 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,31 @@ jobs:
name: Deploy to GitHub Pages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
- name: Checkout
uses: actions/checkout@v6
with:
version: 9.14.2
persist-credentials: false
- uses: pnpm/action-setup@v6
with:
cache: true
package_json_file: site/package.json
cache_dependency_path: site/pnpm-lock.yaml
- uses: actions/setup-node@v4
Comment on lines +14 to 23

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 | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate and display the workflow section around the reported lines
FILE=".github/workflows/deploy-docs.yml"
echo "=== File: $FILE ==="
nl -ba "$FILE" | sed -n '1,120p'
echo "=== End excerpt ==="

# Grep for uses lines and relevant inputs
echo "=== action uses (context) ==="
rg -n "uses:\s|persist-credentials|pnpm/action-setup|setup-node" "$FILE" -n || true

# Show any with: blocks under pnpm/action-setup / checkout / setup-node
echo "=== pnpm/action-setup block ==="
rg -n "pnpm/action-setup" -n "$FILE" || true
# Print a small window around pnpm/action-setup
line=$(rg -n "pnpm/action-setup" "$FILE" | head -n1 | cut -d: -f1 || true)
if [[ -n "${line:-}" ]]; then
  start=$((line-8)); end=$((line+20))
  nl -ba "$FILE" | sed -n "${start},${end}p"
fi

echo "=== checkout persist-credentials ==="
rg -n "actions/checkout" "$FILE" || true
rg -n "persist-credentials" "$FILE" || true

echo "=== checkout node setup context ==="
rg -n "actions/checkout@|actions/setup-node@|setup-node@|actions/checkout" "$FILE" || true

Repository: Rat-OS/RatOS

Length of output: 165


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=".github/workflows/deploy-docs.yml"

echo "=== File exists? ==="
ls -la "$FILE"

echo "=== Full file (with line numbers via awk) ==="
awk '{print FNR ":" $0}' "$FILE" | sed -n '1,220p'

echo "=== Focus: lines 1-80 (for reported range sanity) ==="
awk '{print FNR ":" $0}' "$FILE" | sed -n '1,80p'

echo "=== Matches: uses/setup/checkout/pnpm/action-setup ==="
rg -n "uses:\s*|actions/checkout|actions/setup-node|pnpm/action-setup|persist-credentials|with:" "$FILE" || true

echo "=== Extract checkout block (around uses: actions/checkout) ==="
line=$(rg -n "uses:\s*actions/checkout" "$FILE" | head -n1 | cut -d: -f1 || true)
if [[ -n "${line:-}" ]]; then
  start=$((line-6)); end=$((line+12))
  awk -v s="$start" -v e="$end" '{if(FNR>=s && FNR<=e) print FNR ":" $0}' "$FILE"
fi

echo "=== Extract pnpm/action-setup block ==="
line=$(rg -n "uses:\s*pnpm/action-setup" "$FILE" | head -n1 | cut -d: -f1 || true)
if [[ -n "${line:-}" ]]; then
  start=$((line-6)); end=$((line+18))
  awk -v s="$start" -v e="$end" '{if(FNR>=s && FNR<=e) print FNR ":" $0}' "$FILE"
fi

echo "=== Extract actions/setup-node block ==="
line=$(rg -n "uses:\s*actions/setup-node" "$FILE" | head -n1 | cut -d: -f1 || true)
if [[ -n "${line:-}" ]]; then
  start=$((line-6)); end=$((line+14))
  awk -v s="$start" -v e="$end" '{if(FNR>=s && FNR<=e) print FNR ":" $0}' "$FILE"
fi

Repository: Rat-OS/RatOS

Length of output: 5408


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Files ==="
ls -la
echo "=== site/package.json ==="
if [[ -f site/package.json ]]; then
  sed -n '1,120p' site/package.json
  echo "=== packageManager field ==="
  rg -n '"packageManager"\s*:' site/package.json || true
else
  echo "site/package.json not found"
fi

echo "=== root package.json ==="
if [[ -f package.json ]]; then
  sed -n '1,120p' package.json
  echo "=== packageManager field ==="
  rg -n '"packageManager"\s*:' package.json || true
else
  echo "root package.json not found"
fi

echo "=== Check if deploy-docs.yml has any persist-credentials or pnpm/action-setup with: config ==="
rg -n "persist-credentials|package_json_file|packageManager|with:" .github/workflows/deploy-docs.yml || true

Repository: Rat-OS/RatOS

Length of output: 3982


🌐 Web query:

actions/checkout persist-credentials default value

💡 Result:

The actions/checkout input persist-credentials has the default value true (i.e., it persists the token/credentials by default). This is stated by GitHub’s checkout documentation as “Default: true” for persist-credentials, and the docs also describe that it can be opted out by setting persist-credentials: false.[1][2] Brief context: when persist-credentials is enabled, the auth token is persisted in the local git config so later steps can run authenticated git commands; the token is removed during post-job cleanup, and you can disable persistence with persist-credentials: false.[1][2]

Citations:


🌐 Web query:

pnpm/action-setup package_json_file default reads repository root package.json packageManager input

💡 Result:

Default behavior: pnpm/action-setup’s package_json_file input defaults to reading package.json from the repository root (path “package.json”). [1] The action documents that package_json_file is optional with default value package.json. That means if you don’t set package_json_file, it will look for packageManager in the root-level package.json and (when you omit the version input) use the pnpm version from that packageManager field. [1] If your repo doesn’t have a root package.json or you want to point at a different one (e.g., a monorepo subfolder), you must set package_json_file accordingly. [1] (Implementation detail) The action also treats package_json_file as a path input and normalizes/expands it before using it to read the packageManager configuration. [2]

Citations:


🌐 Web query:

pnpm/action-setup inputs version package_json_file packageManager inference behavior

💡 Result:

pnpm/action-setup: inputs + version/packageManager inference behavior 1) with: version - Meaning: “Version of pnpm to install.” [1] - Optionality/inference: - It is optional when your repo’s package.json contains a packageManager field. [1] - Otherwise it is required. [1] - “Version” parsing/inference: the input supports npm-style versioning formats such as exact versions (e.g. 6.24.1), version ranges (e.g. 6, 6.x.x, 6.24.x), caret ranges (e.g. ^6.24.1), wildcards (*), and also latest. [1] 2) with: package_json_file - Meaning: Optional file path (default package.json) to read “packageManager” configuration from. [1] - Inference behavior tie-in: - When you omit with.version, the action will read the packageManager field from the file specified by package_json_file (defaulting to package.json) to determine which pnpm version to install. [1] 3) packageManager field (conceptually, in your package.json) - This is not an action input; it’s a field in the project’s package.json that pnpm/action-setup reads (from package_json_file) to infer the pnpm version when with.version is omitted. [1] Overall decision logic - If packageManager exists in the specified package_json_file: you may omit with.version and pnpm/action-setup installs the pnpm version from that field. [1] - If packageManager does not exist: with.version becomes required. [1] (Implementation note: the action’s input processing expands package_json_file and retrieves version via its input processing layer.) [2]

Citations:


Pin deploy-docs workflow action refs to SHAs and harden checkout/pnpm version sourcing

In .github/workflows/deploy-docs.yml (lines 14-17), actions/checkout@v6, pnpm/action-setup@v6, and actions/setup-node@v4 use floating tags—pin them to full commit SHAs. actions/checkout also lacks with: persist-credentials: false, so it keeps credentials (default is true).

Additionally, pnpm/action-setup@v6 has no with.version and no with.package_json_file, so it defaults to reading package.json from the repo root; this repo has no root package.json, so it won’t reliably use site/package.json’s packageManager pin.

🔒 Suggested hardening
-      - name: Checkout
-        uses: actions/checkout@v6
+      - name: Checkout
+        uses: actions/checkout@<FULL_COMMIT_SHA>
+        with:
+          persist-credentials: false
-      - uses: pnpm/action-setup@v6
+      - uses: pnpm/action-setup@<FULL_COMMIT_SHA>
-      - uses: actions/setup-node@v4
+      - uses: actions/setup-node@<FULL_COMMIT_SHA>
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 14-15: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 15-15: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 16-16: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 17-17: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 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-docs.yml around lines 14 - 17, The workflow uses
floating action refs and leaves checkout credentials and pnpm sourcing unpinned:
replace actions/checkout@v6, pnpm/action-setup@v6, and actions/setup-node@v4
with their corresponding full commit SHAs, add with: persist-credentials: false
to the actions/checkout step, and configure the pnpm/action-setup step to
include explicit with.version and with.package_json_file pointing to
site/package.json so pnpm reads the correct packageManager pin; ensure the
setup-node step is also referenced by SHA and any node-version is explicitly
provided (or pinned) instead of relying on defaults.

with:
node-version: 20.
cache: 'pnpm'
cache-dependency-path: site/pnpm-lock.yaml
node-version: 24

- name: Build website
working-directory: site
run: |
pnpm install --frozen-lockfile
pnpm run build

- name: Commit changes
id: extract_repo_name
run: |
# Extract only the repo name from 'owner/repo-name'
echo "repo_name=$(echo "${{ github.repository }}" | cut -d'/' -f2)" >> "$GITHUB_OUTPUT"

# Popular action to deploy to GitHub Pages:
# Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus
- name: Deploy to GitHub Pages
Expand All @@ -34,5 +44,5 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
# Build output to publish to the `gh-pages` branch:
publish_dir: ./docs
user_name: Mikkel Schmidt
user_email: mikkel.schmidt@gmail.com
user_name: ${{ steps.extract_repo_name.outputs.repo_name }}
user_email: actions@github.com
3 changes: 2 additions & 1 deletion site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,6 @@
"last 1 firefox version",
"last 1 safari version"
]
}
},
"packageManager": "pnpm@11.2.2+sha512.36e6621fad506178936455e70247b8808ef4ec25797a9f437a93281a020484e2607f6a469a22e982987c3dbb8866e3071514ab10a4a1749e06edcd1ec118436f"
}
6 changes: 6 additions & 0 deletions site/pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
allowBuilds:
'@swc/core': true
'@tsparticles/engine': true
core-js: true
core-js-pure: true
sharp: true