Skip to content

Commit 3cadd50

Browse files
Migrate to new-style architecture: provision nix devShell
The nix runtime branch created a NixEnvironment at SourceLocation but nothing provided the flake.nix it needs, so the nix lifecycle subtest failed (no flake) — which is why this agent was quarantined. Embed a flake (python3 + uv), write it into the source dir when the project doesn't ship one (ensureNixFlake), and provision it in the matrix test. Matrix now passes native + nix + docker. Un-quarantined. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 7ca48a3 commit 3cadd50

7 files changed

Lines changed: 112 additions & 4 deletions

File tree

‎agent.codefly.yaml‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,3 @@ publisher: codefly.dev
22
kind: codefly:service
33
name: python-fastapi
44
version: 0.0.88
5-
quarantine: true
6-
quarantine_reason: "not yet migrated to the new-style agent architecture; skipped by bulk build until migrated"

‎go.sum‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJ
3737
github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
3838
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
3939
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
40-
github.com/codefly-dev/core v0.2.9 h1:WPH+FxwoO56CxJokPzv8+PrLjCWgjBHydr36mYIqoRU=
41-
github.com/codefly-dev/core v0.2.9/go.mod h1:TjQHrrRNmEX+gRQIXsSqNqh4CITsR1P5HvMrYWeoIzc=
4240
github.com/codefly-dev/gortk v0.0.0-20260621170842-c2212b7ad788 h1:9felyfj2/63GU24Ermsx2pC6DmfWkLMbWV8DgLLNt1U=
4341
github.com/codefly-dev/gortk v0.0.0-20260621170842-c2212b7ad788/go.mod h1:dDWUMFgAP063OCGhTEpV7FFUj9+zTcxxO/nV80VKEwg=
4442
github.com/codefly-dev/service-python v0.0.1 h1:asSY/6l/jlYfFN+ZsOqJAktR1Q0Bg22FT+aPQKesU4I=

‎lifecycle_matrix_test.go‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"os"
7+
"path/filepath"
78
"strings"
89
"testing"
910

@@ -24,6 +25,19 @@ func TestPythonFastAPILifecycle_Matrix(t *testing.T) {
2425
}
2526
defer os.RemoveAll(dir)
2627

28+
// Provision the nix devShell (python3 + uv) into the work dir so the nix
29+
// backend has a flake to materialize — mirrors what the runtime does via
30+
// ensureNixFlake. Without it the nix subtest has no flake and fails.
31+
for _, f := range []string{"flake.nix", "flake.lock"} {
32+
data, rerr := os.ReadFile(filepath.Join("nix", f))
33+
if rerr != nil {
34+
t.Fatalf("read nix/%s: %v", f, rerr)
35+
}
36+
if werr := os.WriteFile(filepath.Join(dir, f), data, 0o644); werr != nil {
37+
t.Fatalf("write %s: %v", f, werr)
38+
}
39+
}
40+
2741
// python:3.12-slim has /usr/local/bin/python3 directly, no entrypoint
2842
// wrapper. The runtime (main.go) uses the uv-bundled image for actual
2943
// service execution; this matrix test just validates toolchain reach

‎nix/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.

‎nix/flake.nix‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
description = "codefly python-fastapi service: nix runtime";
3+
4+
inputs = {
5+
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
6+
};
7+
8+
outputs = { self, nixpkgs }:
9+
let
10+
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
11+
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f system);
12+
in
13+
{
14+
# devShell exposes python3 + uv so the codefly NixEnvironment runs the
15+
# FastAPI service (uv sync / uv run) reproducibly — no system python needed.
16+
devShells = forAllSystems (system:
17+
let
18+
pkgs = nixpkgs.legacyPackages.${system};
19+
in
20+
{
21+
default = pkgs.mkShell {
22+
packages = [
23+
pkgs.python3
24+
pkgs.uv
25+
];
26+
};
27+
});
28+
};
29+
}

‎nixflake.go‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package main
2+
3+
// nixflake.go — provisions the nix devShell for the nix runtime.
4+
//
5+
// In nix mode the agent runs the FastAPI service through a NixEnvironment rooted
6+
// at the service source dir (CreateRunnerEnvironment), which materializes the
7+
// devShell from a flake.nix there. User projects don't ship one, so this embeds
8+
// a codefly flake (python3 + uv) and writes it into the source dir when absent —
9+
// a user-supplied flake.nix is respected (never overwritten).
10+
11+
import (
12+
_ "embed"
13+
"fmt"
14+
"os"
15+
"path/filepath"
16+
)
17+
18+
//go:embed nix/flake.nix
19+
var nixFlakeNix string
20+
21+
//go:embed nix/flake.lock
22+
var nixFlakeLock string
23+
24+
// ensureNixFlake writes the embedded flake (python3 + uv) into dir unless a
25+
// flake.nix already exists there.
26+
func ensureNixFlake(dir string) error {
27+
if _, err := os.Stat(filepath.Join(dir, "flake.nix")); err == nil {
28+
return nil // user (or a prior run) already provides one
29+
}
30+
if err := os.WriteFile(filepath.Join(dir, "flake.nix"), []byte(nixFlakeNix), 0o644); err != nil {
31+
return fmt.Errorf("write flake.nix: %w", err)
32+
}
33+
if err := os.WriteFile(filepath.Join(dir, "flake.lock"), []byte(nixFlakeLock), 0o644); err != nil {
34+
return fmt.Errorf("write flake.lock: %w", err)
35+
}
36+
return nil
37+
}

‎runtime.go‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,11 @@ func (s *Runtime) CreateRunnerEnvironment(ctx context.Context) error {
150150
s.runnerEnvironment = dockerEnv
151151

152152
case s.Base.Runtime.IsNixRuntime():
153+
// Provision the devShell (python3 + uv) when the project doesn't ship a
154+
// flake.nix, so NewNixEnvironment has something to materialize.
155+
if err := ensureNixFlake(s.Service.SourceLocation); err != nil {
156+
return s.Wool.Wrapf(err, "cannot provision nix flake")
157+
}
153158
nixEnv, err := runners.NewNixEnvironment(ctx, s.Service.SourceLocation)
154159
if err != nil {
155160
return s.Wool.Wrapf(err, "cannot create nix runner")

0 commit comments

Comments
 (0)