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
120 changes: 120 additions & 0 deletions .github/workflows/update-pnpm-hash.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
name: Update pnpm deps Nix hash

on:
pull_request:
paths:
- pnpm-lock.yaml

concurrency:
group: pnpm-hash-${{ github.event.pull_request.number }}
cancel-in-progress: true

permissions:
contents: write

jobs:
update-pnpm-hash:
runs-on:
- codebuild-defguard-client-runner-${{ github.run_id }}-${{ github.run_attempt }}

steps:
- uses: actions/checkout@v5
with:
# Check out the exact PR head commit so the sha we pass to the API
# matches what we read from disk - avoids a race if the branch is
# updated while this job is in flight.
ref: ${{ github.event.pull_request.head.sha }}
submodules: recursive

- uses: cachix/install-nix-action@v31
with:
install_options: --no-daemon
extra_nix_config: |
experimental-features = nix-command flakes

- name: Compute correct pnpm deps hash
id: hash
run: |
set -euo pipefail

echo "=== starting hash computation ==="
echo "nix: $(which nix 2>/dev/null || echo 'NOT IN PATH')"
echo "nix version: $(nix --version 2>/dev/null || echo 'unavailable')"

# A valid-format but always-wrong sha256 hash.
# Identical to lib.fakeHash in nixpkgs.
FAKE="sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="

# Extract the current pnpm hash.
CURRENT=$(sed -n 's/^[[:space:]]*hash = "\(sha256-[^"]*\)".*/\1/p' nix/package.nix | head -1)
if [ -z "$CURRENT" ]; then
echo "::error::Could not extract current hash from nix/package.nix"
exit 1
fi
echo "current hash: ${CURRENT}"
echo "current=${CURRENT}" >> "$GITHUB_OUTPUT"

# Swap in the fake hash so Nix will fail and report the real one.
sed -i "s|hash = \"${CURRENT}\"|hash = \"${FAKE}\"|" nix/package.nix

# Build only the pnpmDeps fixed-output derivation.
SYSTEM=$(nix eval --impure --raw --expr 'builtins.currentSystem')
echo "building pnpmDeps for ${SYSTEM}..."
BUILD_LOG=$(nix build --no-link --no-write-lock-file \
".#packages.${SYSTEM}.default.pnpmDeps" 2>&1 || true)

# Nix prints "got: sha256-..." in the hash mismatch error.
NEW=$(printf '%s' "$BUILD_LOG" | sed -n 's/.*got:[[:space:]]*\(sha256-[^[:space:]]*\).*/\1/p' | head -1)
if [ -z "$NEW" ]; then
echo "::error::Could not extract the correct hash from nix output."
echo "Full build log:"
printf '%s\n' "$BUILD_LOG"
exit 1
fi

echo "new hash: ${NEW}"
echo "new=${NEW}" >> "$GITHUB_OUTPUT"

# Write the correct hash back into the file.
sed -i "s|hash = \"${FAKE}\"|hash = \"${NEW}\"|" nix/package.nix

# Only commit when the hash actually changed; skip if it was already correct.
- name: Commit updated hash
if: steps.hash.outputs.current != steps.hash.outputs.new
uses: actions/github-script@v7
env:
OLD_HASH: ${{ steps.hash.outputs.current }}
NEW_HASH: ${{ steps.hash.outputs.new }}
with:
script: |
const fs = require('fs');
const content = fs.readFileSync('nix/package.nix', 'utf8');
// GraphQL createCommitOnBranch requires base64-encoded file contents.
const encoded = Buffer.from(content).toString('base64');

// The GraphQL createCommitOnBranch mutation creates commits that
// GitHub signs automatically - producing a Verified badge.
await github.graphql(`
mutation CreateCommit($input: CreateCommitOnBranchInput!) {
createCommitOnBranch(input: $input) {
commit { url }
}
}
`, {
input: {
branch: {
repositoryNameWithOwner: `${context.repo.owner}/${context.repo.repo}`,
branchName: context.payload.pull_request.head.ref,
},
message: { headline: 'chore(nix): update pnpm deps hash' },
fileChanges: {
additions: [{ path: 'nix/package.nix', contents: encoded }],
},
// Safety check - fails if the branch moved under us.
expectedHeadOid: context.payload.pull_request.head.sha,
},
});

console.log(
`pnpm deps hash updated: ${process.env.OLD_HASH} -> ${process.env.NEW_HASH}`
);
12 changes: 9 additions & 3 deletions nix/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ in
;

fetcherVersion = 2;
hash = "sha256-vDLgpFaO+48s+tj1/2m2fgNJpCfnNkFJpQkC4Xah59E=";
hash = "sha256-XXsR+zc4HsHByzzd2oHyAOrrpH9t2juUcAIoimlukbc=";
};

buildPhase = ''
Expand Down Expand Up @@ -138,13 +138,19 @@ in
lib.makeBinPath [
# `defguard-service` needs `ip` to manage WireGuard
pkgs.iproute2
# `defguard-service` needs `resolvconf` to manage DNS
pkgs.openresolv
# `defguard-client` needs `update-desktop-database` and `lsb_release`
pkgs.desktop-file-utils
pkgs.lsb-release
]
}
# `defguard-service` needs `resolvconf` to manage DNS. openresolv is
# added as a suffix so the system PATH is checked first - on systems
# with services.resolved enabled, NixOS puts systemd's resolvconf compat
# there, which correctly integrates with systemd-resolved. openresolv
# serves as a fallback for systems that don't use systemd-resolved.
# Same approach used to fix the identical wg-quick issue in nixpkgs:
# https://github.com/NixOS/nixpkgs/issues/139526
--suffix PATH : ${lib.makeBinPath [pkgs.openresolv]}
--prefix LD_LIBRARY_PATH : ${
lib.makeLibraryPath [
pkgs.libayatana-appindicator
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"@react-hook/resize-observer": "^2.0.2",
"@stablelib/base64": "^2.0.1",
"@stablelib/x25519": "^2.0.1",
"@tanstack/query-core": "^5.100.9",
"@tanstack/query-core": "^5.100.10",
"@tanstack/react-virtual": "^3.13.24",
"@tauri-apps/api": "^2.11.0",
"@tauri-apps/plugin-clipboard-manager": "^2.3.2",
Expand Down Expand Up @@ -115,12 +115,12 @@
"@biomejs/biome": "^2.4.15",
"@hookform/devtools": "^4.4.0",
"@svgr/cli": "^8.1.0",
"@tanstack/react-query": "^5.100.9",
"@tanstack/react-query-devtools": "^5.100.9",
"@tanstack/react-query": "^5.100.10",
"@tanstack/react-query-devtools": "^5.100.10",
"@tauri-apps/cli": "^2.11.1",
"@types/file-saver": "^2.0.7",
"@types/lodash-es": "^4.17.12",
"@types/node": "^24.12.3",
"@types/node": "^24.12.4",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.2.0",
Expand Down
Loading