Skip to content

Commit 5e13527

Browse files
Alb-Oopencodeopencode-agent[bot]
authored
feat: nix support for the nix folks (#3924)
Co-authored-by: opencode <opencode@sst.dev> Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
1 parent aba94c6 commit 5e13527

15 files changed

Lines changed: 869 additions & 8 deletions

File tree

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
name: Update Nix Hashes
2+
3+
permissions:
4+
contents: write
5+
6+
on:
7+
workflow_dispatch:
8+
push:
9+
paths:
10+
- 'bun.lock'
11+
- 'package.json'
12+
- 'packages/*/package.json'
13+
pull_request:
14+
paths:
15+
- 'bun.lock'
16+
- 'package.json'
17+
- 'packages/*/package.json'
18+
19+
jobs:
20+
update:
21+
runs-on: ubuntu-latest
22+
env:
23+
SYSTEM: x86_64-linux
24+
25+
steps:
26+
- name: Checkout repository
27+
uses: actions/checkout@v4
28+
with:
29+
token: ${{ secrets.GITHUB_TOKEN }}
30+
fetch-depth: 0
31+
32+
- name: Setup Nix
33+
uses: DeterminateSystems/nix-installer-action@v20
34+
35+
- name: Configure git
36+
run: |
37+
git config --global user.email "opencode@sst.dev"
38+
git config --global user.name "opencode"
39+
40+
- name: Update node_modules hash
41+
run: |
42+
set -euo pipefail
43+
nix/scripts/update-hashes.sh
44+
45+
- name: Commit hash changes
46+
env:
47+
TARGET_BRANCH: ${{ github.head_ref || github.ref_name }}
48+
run: |
49+
set -euo pipefail
50+
51+
summarize() {
52+
local status="$1"
53+
{
54+
echo "### Nix Hash Update"
55+
echo ""
56+
echo "- ref: ${GITHUB_REF_NAME}"
57+
echo "- status: ${status}"
58+
} >> "$GITHUB_STEP_SUMMARY"
59+
if [ -n "${GITHUB_SERVER_URL:-}" ] && [ -n "${GITHUB_REPOSITORY:-}" ] && [ -n "${GITHUB_RUN_ID:-}" ]; then
60+
echo "- run: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" >> "$GITHUB_STEP_SUMMARY"
61+
fi
62+
echo "" >> "$GITHUB_STEP_SUMMARY"
63+
}
64+
65+
FILES=(flake.nix nix/node-modules.nix nix/hashes.json)
66+
STATUS="$(git status --short -- "${FILES[@]}" || true)"
67+
if [ -z "$STATUS" ]; then
68+
summarize "no changes"
69+
echo "No changes to tracked Nix files. Hashes are already up to date."
70+
exit 0
71+
fi
72+
73+
git add "${FILES[@]}"
74+
git commit -m "Update Nix hashes"
75+
76+
BRANCH="${TARGET_BRANCH:-${GITHUB_REF_NAME}}"
77+
git push origin HEAD:"$BRANCH"
78+
79+
summarize "committed $(git rev-parse --short HEAD)"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ dist
1313
.turbo
1414
**/.serena
1515
.serena/
16+
/result
1617
refs
1718
Session.vim
1819
opencode.json

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ curl -fsSL https://opencode.ai/install | bash
2828
npm i -g opencode-ai@latest # or bun/pnpm/yarn
2929
scoop bucket add extras; scoop install extras/opencode # Windows
3030
choco install opencode # Windows
31-
brew install opencode # macOS and Linux
31+
brew install opencode # macOS and Linux
3232
paru -S opencode-bin # Arch Linux
3333
mise use --pin -g ubi:sst/opencode # Any OS
34+
nix run nixpkgs#opencode # or github:sst/opencode for latest dev branch
3435
```
3536

3637
> [!TIP]

flake.lock

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
{
2+
description = "OpenCode development flake";
3+
4+
inputs = {
5+
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
6+
};
7+
8+
outputs =
9+
{
10+
nixpkgs,
11+
...
12+
}:
13+
let
14+
systems = [
15+
"aarch64-linux"
16+
"x86_64-linux"
17+
"aarch64-darwin"
18+
"x86_64-darwin"
19+
];
20+
lib = nixpkgs.lib;
21+
forEachSystem = lib.genAttrs systems;
22+
pkgsFor = system: nixpkgs.legacyPackages.${system};
23+
packageJson = builtins.fromJSON (builtins.readFile ./packages/opencode/package.json);
24+
bunTarget = {
25+
"aarch64-linux" = "bun-linux-arm64";
26+
"x86_64-linux" = "bun-linux-x64";
27+
"aarch64-darwin" = "bun-darwin-arm64";
28+
"x86_64-darwin" = "bun-darwin-x64";
29+
};
30+
defaultNodeModules = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
31+
hashesFile = "${./nix}/hashes.json";
32+
hashesData =
33+
if builtins.pathExists hashesFile then builtins.fromJSON (builtins.readFile hashesFile) else { };
34+
nodeModulesHash = hashesData.nodeModules or defaultNodeModules;
35+
modelsDev = forEachSystem (
36+
system:
37+
let
38+
pkgs = pkgsFor system;
39+
in
40+
pkgs."models-dev"
41+
);
42+
in
43+
{
44+
devShells = forEachSystem (
45+
system:
46+
let
47+
pkgs = pkgsFor system;
48+
in
49+
{
50+
default = pkgs.mkShell {
51+
packages = with pkgs; [
52+
bun
53+
nodejs_20
54+
pkg-config
55+
openssl
56+
git
57+
];
58+
};
59+
}
60+
);
61+
62+
packages = forEachSystem (
63+
system:
64+
let
65+
pkgs = pkgsFor system;
66+
mkNodeModules = pkgs.callPackage ./nix/node-modules.nix {
67+
hash = nodeModulesHash;
68+
};
69+
mkPackage = pkgs.callPackage ./nix/opencode.nix { };
70+
in
71+
{
72+
default = mkPackage {
73+
version = packageJson.version;
74+
src = ./.;
75+
scripts = ./nix/scripts;
76+
target = bunTarget.${system};
77+
modelsDev = "${modelsDev.${system}}/dist/_api.json";
78+
mkNodeModules = mkNodeModules;
79+
};
80+
}
81+
);
82+
83+
apps = forEachSystem (
84+
system:
85+
let
86+
pkgs = pkgsFor system;
87+
in
88+
{
89+
opencode-dev = {
90+
type = "app";
91+
meta = {
92+
description = "Nix devshell shell for OpenCode";
93+
runtimeInputs = [ pkgs.bun ];
94+
};
95+
program = "${
96+
pkgs.writeShellApplication {
97+
name = "opencode-dev";
98+
text = ''
99+
exec bun run dev "$@"
100+
'';
101+
}
102+
}/bin/opencode-dev";
103+
};
104+
}
105+
);
106+
};
107+
}

nix/hashes.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"nodeModules": "sha256-srbGIRjvpqUF+jWq4GAx7sGAasq02dRySnxTjijJJT8="
3+
}

nix/node-modules.nix

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{ hash, lib, stdenvNoCC, bun, cacert, curl }:
2+
args:
3+
stdenvNoCC.mkDerivation {
4+
pname = "opencode-node_modules";
5+
version = args.version;
6+
src = args.src;
7+
8+
impureEnvVars =
9+
lib.fetchers.proxyImpureEnvVars
10+
++ [
11+
"GIT_PROXY_COMMAND"
12+
"SOCKS_SERVER"
13+
];
14+
15+
nativeBuildInputs = [ bun cacert curl ];
16+
17+
dontConfigure = true;
18+
19+
buildPhase = ''
20+
runHook preBuild
21+
export HOME=$(mktemp -d)
22+
export BUN_INSTALL_CACHE_DIR=$(mktemp -d)
23+
bun install \
24+
--cpu="*" \
25+
--os="*" \
26+
--frozen-lockfile \
27+
--ignore-scripts \
28+
--no-progress \
29+
--linker=isolated
30+
bun --bun ${args.canonicalizeScript}
31+
bun --bun ${args.normalizeBinsScript}
32+
runHook postBuild
33+
'';
34+
35+
installPhase = ''
36+
runHook preInstall
37+
mkdir -p $out
38+
while IFS= read -r dir; do
39+
rel="''${dir#./}"
40+
dest="$out/$rel"
41+
mkdir -p "$(dirname "$dest")"
42+
cp -R "$dir" "$dest"
43+
done < <(find . -type d -name node_modules -prune | sort)
44+
runHook postInstall
45+
'';
46+
47+
dontFixup = true;
48+
49+
outputHashAlgo = "sha256";
50+
outputHashMode = "recursive";
51+
outputHash = hash;
52+
}

0 commit comments

Comments
 (0)