Skip to content
Closed
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
4 changes: 1 addition & 3 deletions .github/workflows/nix-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ on:
- "nix/**"
- "packages/app/**"
- "packages/desktop/**"
- ".github/workflows/nix-desktop.yml"
pull_request:
paths:
- "flake.nix"
- "flake.lock"
- "nix/**"
- "packages/app/**"
- "packages/desktop/**"
- ".github/workflows/nix-desktop.yml"
workflow_dispatch:

jobs:
Expand All @@ -28,7 +26,7 @@ jobs:
os:
- blacksmith-4vcpu-ubuntu-2404
- blacksmith-4vcpu-ubuntu-2404-arm
- macos-15-intel
- macos-15
- macos-latest
runs-on: ${{ matrix.os }}
timeout-minutes: 60
Expand Down
202 changes: 32 additions & 170 deletions .github/workflows/update-nix-hashes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ on:
- "bun.lock"
- "package.json"
- "packages/*/package.json"
- ".github/workflows/update-nix-hashes.yml"
pull_request:
paths:
- "bun.lock"
- "package.json"
- "packages/*/package.json"
- ".github/workflows/update-nix-hashes.yml"

jobs:
update-flake:
Expand All @@ -27,7 +25,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
Expand All @@ -45,17 +43,17 @@ jobs:
- name: Update ${{ env.TITLE }}
run: |
set -euo pipefail
echo "Updating $TITLE..."
echo "📦 Updating $TITLE..."
nix flake update
echo "$TITLE updated successfully"
echo "$TITLE updated successfully"

- name: Commit ${{ env.TITLE }} changes
env:
TARGET_BRANCH: ${{ github.head_ref || github.ref_name }}
run: |
set -euo pipefail

echo "Checking for changes in tracked files..."
echo "🔍 Checking for changes in tracked files..."

summarize() {
local status="$1"
Expand All @@ -73,29 +71,29 @@ jobs:
FILES=(flake.lock flake.nix)
STATUS="$(git status --short -- "${FILES[@]}" || true)"
if [ -z "$STATUS" ]; then
echo "No changes detected."
echo "No changes detected."
summarize "no changes"
exit 0
fi

echo "Changes detected:"
echo "📝 Changes detected:"
echo "$STATUS"
echo "Staging files..."
echo "🔗 Staging files..."
git add "${FILES[@]}"
echo "Committing changes..."
echo "💾 Committing changes..."
git commit -m "Update $TITLE"
echo "Changes committed"
echo "Changes committed"

BRANCH="${TARGET_BRANCH:-${GITHUB_REF_NAME}}"
echo "Pulling latest from branch: $BRANCH"
git pull --rebase --autostash origin "$BRANCH"
echo "Pushing changes to branch: $BRANCH"
echo "🌳 Pulling latest from branch: $BRANCH"
git pull --rebase origin "$BRANCH"
echo "🚀 Pushing changes to branch: $BRANCH"
git push origin HEAD:"$BRANCH"
echo "Changes pushed successfully"
echo "Changes pushed successfully"

summarize "committed $(git rev-parse --short HEAD)"

compute-node-modules-hash:
update-node-modules-hash:
needs: update-flake
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
strategy:
Expand All @@ -113,10 +111,11 @@ jobs:
runs-on: ${{ matrix.host }}
env:
SYSTEM: ${{ matrix.system }}
TITLE: node_modules hash (${{ matrix.system }})

steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
Expand All @@ -126,104 +125,6 @@ jobs:
- name: Setup Nix
uses: nixbuild/nix-quick-install-action@v34

- name: Compute node_modules hash
run: |
set -euo pipefail

DUMMY="sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
HASH_FILE="nix/hashes.json"
OUTPUT_FILE="hash-${SYSTEM}.txt"

export NIX_KEEP_OUTPUTS=1
export NIX_KEEP_DERIVATIONS=1

BUILD_LOG=$(mktemp)
TMP_JSON=$(mktemp)
trap 'rm -f "$BUILD_LOG" "$TMP_JSON"' EXIT

if [ ! -f "$HASH_FILE" ]; then
mkdir -p "$(dirname "$HASH_FILE")"
echo '{"nodeModules":{}}' > "$HASH_FILE"
fi

# Set dummy hash to force nix to rebuild and reveal correct hash
jq --arg system "$SYSTEM" --arg value "$DUMMY" \
'.nodeModules = (.nodeModules // {}) | .nodeModules[$system] = $value' "$HASH_FILE" > "$TMP_JSON"
mv "$TMP_JSON" "$HASH_FILE"

MODULES_ATTR=".#packages.${SYSTEM}.default.node_modules"
DRV_PATH="$(nix eval --raw "${MODULES_ATTR}.drvPath")"

echo "Building node_modules for ${SYSTEM} to discover correct hash..."
echo "Attempting to realize derivation: ${DRV_PATH}"
REALISE_OUT=$(nix-store --realise "$DRV_PATH" --keep-failed 2>&1 | tee "$BUILD_LOG" || true)

BUILD_PATH=$(echo "$REALISE_OUT" | grep "^/nix/store/" | head -n1 || true)
CORRECT_HASH=""

if [ -n "$BUILD_PATH" ] && [ -d "$BUILD_PATH" ]; then
echo "Realized node_modules output: $BUILD_PATH"
CORRECT_HASH=$(nix hash path --sri "$BUILD_PATH" 2>/dev/null || true)
fi

# Try to extract hash from build log
if [ -z "$CORRECT_HASH" ]; then
CORRECT_HASH="$(grep -E 'got:\s+sha256-[A-Za-z0-9+/=]+' "$BUILD_LOG" | awk '{print $2}' | head -n1 || true)"
fi

if [ -z "$CORRECT_HASH" ]; then
CORRECT_HASH="$(grep -A2 'hash mismatch' "$BUILD_LOG" | grep 'got:' | awk '{print $2}' | sed 's/sha256:/sha256-/' || true)"
fi

# Try to hash from kept failed build directory
if [ -z "$CORRECT_HASH" ]; then
KEPT_DIR=$(grep -oE "build directory.*'[^']+'" "$BUILD_LOG" | grep -oE "'/[^']+'" | tr -d "'" | head -n1 || true)
if [ -z "$KEPT_DIR" ]; then
KEPT_DIR=$(grep -oE '/nix/var/nix/builds/[^ ]+' "$BUILD_LOG" | head -n1 || true)
fi

if [ -n "$KEPT_DIR" ] && [ -d "$KEPT_DIR" ]; then
HASH_PATH="$KEPT_DIR"
[ -d "$KEPT_DIR/build" ] && HASH_PATH="$KEPT_DIR/build"

if [ -d "$HASH_PATH/node_modules" ]; then
CORRECT_HASH=$(nix hash path --sri "$HASH_PATH" 2>/dev/null || true)
fi
fi
fi

if [ -z "$CORRECT_HASH" ]; then
echo "Failed to determine correct node_modules hash for ${SYSTEM}."
cat "$BUILD_LOG"
exit 1
fi

echo "$CORRECT_HASH" > "$OUTPUT_FILE"
echo "Hash for ${SYSTEM}: $CORRECT_HASH"

- name: Upload hash artifact
uses: actions/upload-artifact@v6
with:
name: hash-${{ matrix.system }}
path: hash-${{ matrix.system }}.txt
retention-days: 1

commit-node-modules-hashes:
needs: compute-node-modules-hash
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
runs-on: blacksmith-4vcpu-ubuntu-2404
env:
TITLE: node_modules hashes

steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
ref: ${{ github.head_ref || github.ref_name }}
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}

- name: Configure git
run: |
git config --global user.email "[email protected]"
Expand All @@ -234,66 +135,22 @@ jobs:
TARGET_BRANCH: ${{ github.head_ref || github.ref_name }}
run: |
BRANCH="${TARGET_BRANCH:-${GITHUB_REF_NAME}}"
git pull --rebase --autostash origin "$BRANCH"

- name: Download all hash artifacts
uses: actions/download-artifact@v7
with:
pattern: hash-*
merge-multiple: true
git pull origin "$BRANCH"

- name: Merge hashes into hashes.json
- name: Update ${{ env.TITLE }}
run: |
set -euo pipefail

HASH_FILE="nix/hashes.json"

if [ ! -f "$HASH_FILE" ]; then
mkdir -p "$(dirname "$HASH_FILE")"
echo '{"nodeModules":{}}' > "$HASH_FILE"
fi

echo "Merging hashes into ${HASH_FILE}..."

shopt -s nullglob
files=(hash-*.txt)
if [ ${#files[@]} -eq 0 ]; then
echo "No hash files found, nothing to update"
exit 0
fi

EXPECTED_SYSTEMS="x86_64-linux aarch64-linux x86_64-darwin aarch64-darwin"
for sys in $EXPECTED_SYSTEMS; do
if [ ! -f "hash-${sys}.txt" ]; then
echo "WARNING: Missing hash file for $sys"
fi
done

for f in "${files[@]}"; do
system="${f#hash-}"
system="${system%.txt}"
hash=$(cat "$f")
if [ -z "$hash" ]; then
echo "WARNING: Empty hash for $system, skipping"
continue
fi
echo " $system: $hash"
jq --arg sys "$system" --arg h "$hash" \
'.nodeModules = (.nodeModules // {}) | .nodeModules[$sys] = $h' "$HASH_FILE" > "${HASH_FILE}.tmp"
mv "${HASH_FILE}.tmp" "$HASH_FILE"
done

echo "All hashes merged:"
cat "$HASH_FILE"
echo "🔄 Updating $TITLE..."
nix/scripts/update-hashes.sh
echo "✅ $TITLE updated successfully"

- name: Commit ${{ env.TITLE }} changes
env:
TARGET_BRANCH: ${{ github.head_ref || github.ref_name }}
run: |
set -euo pipefail

HASH_FILE="nix/hashes.json"
echo "Checking for changes..."
echo "🔍 Checking for changes in tracked files..."

summarize() {
local status="$1"
Expand All @@ -309,22 +166,27 @@ jobs:
echo "" >> "$GITHUB_STEP_SUMMARY"
}

FILES=("$HASH_FILE")
FILES=(nix/hashes.json)
STATUS="$(git status --short -- "${FILES[@]}" || true)"
if [ -z "$STATUS" ]; then
echo "No changes detected."
echo "No changes detected."
summarize "no changes"
exit 0
fi

echo "Changes detected:"
echo "📝 Changes detected:"
echo "$STATUS"
echo "🔗 Staging files..."
git add "${FILES[@]}"
echo "💾 Committing changes..."
git commit -m "Update $TITLE"
echo "✅ Changes committed"

BRANCH="${TARGET_BRANCH:-${GITHUB_REF_NAME}}"
git pull --rebase --autostash origin "$BRANCH"
echo "🌳 Pulling latest from branch: $BRANCH"
git pull --rebase origin "$BRANCH"
echo "🚀 Pushing changes to branch: $BRANCH"
git push origin HEAD:"$BRANCH"
echo "Changes pushed successfully"
echo "Changes pushed successfully"

summarize "committed $(git rev-parse --short HEAD)"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ target
opencode-dev
logs/
*.bun-build
.opencode/
1 change: 0 additions & 1 deletion STATS.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,3 @@
| 2026-01-13 | 3,297,078 (+243,484) | 1,595,062 (+41,391) | 4,892,140 (+284,875) |
| 2026-01-14 | 3,568,928 (+271,850) | 1,645,362 (+50,300) | 5,214,290 (+322,150) |
| 2026-01-16 | 4,121,550 (+552,622) | 1,754,418 (+109,056) | 5,875,968 (+661,678) |
| 2026-01-17 | 4,389,558 (+268,008) | 1,805,315 (+50,897) | 6,194,873 (+318,905) |
2 changes: 0 additions & 2 deletions github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,8 @@ This will walk you through installing the GitHub app, creating the workflow, and
uses: anomalyco/opencode/github@latest
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
model: anthropic/claude-sonnet-4-20250514
use_github_token: true
```

3. Store the API keys in secrets. In your organization or project **settings**, expand **Secrets and variables** on the left and select **Actions**. Add the required API keys.
Expand Down
2 changes: 1 addition & 1 deletion nix/hashes.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"nodeModules": {
"x86_64-linux": "sha256-4zchRpxzvHnPMcwumgL9yaX0deIXS5IGPp131eYsSvg=",
"aarch64-linux": "sha256-3/BSRsl5pI0Iz3qAFZxIkOehFLZ2Ox9UsbdDHYzqlVg=",
"aarch64-linux": "sha256-0Im52dLeZ0ZtaPJr/U4m7+IRtOfziHNJI/Bu/V6cPho=",
"aarch64-darwin": "sha256-86d/G1q6xiHSSlm+/irXoKLb/yLQbV348uuSrBV70+Q=",
"x86_64-darwin": "sha256-WYaP44PWRGtoG1DIuUJUH4DvuaCuFhlJZ9fPzGsiIfE="
}
Expand Down
Loading
Loading