1import * as Hetzner from "@/Hetzner";
2import * as Test from "@/Test/Alchemy";
3import { describe, expect } from "alchemy-test";
4import * as Effect from "effect/Effect";
5import * as pathe from "pathe";
6import { cloneFixture } from "../../Cloudflare/Utils/Fixture.ts";
7import { expectUrlContains } from "../../Cloudflare/Utils/Http.ts";
8
9const { test } = Test.make({ providers: Hetzner.providers(), dev: true });
10
11const fixtureDir = pathe.resolve(
12 import.meta.dirname,
13 "../../Cloudflare/Website/staticsite-fixture",
14);
15const tempRoot = pathe.resolve(import.meta.dirname, "../../../.tmp");
16
17describe(
18 "Hetzner.Website.StaticSite local",
19 { tags: ["provider:hetzner", "provider:hetzner:website", "local"] },
20 () => {
21 test.provider(
22 "dev builds and serves outdir locally with no cloud resources",
23 (stack) =>
24 Effect.gen(function* () {
25 yield* stack.destroy();
26
27 const cwd = yield* cloneFixture(fixtureDir, {
28 prefix: "alchemy-staticsite-hetzner-local-",
29 tempRoot,
30 entries: ["src", "build.sh"],
31 });
32
33 const deployed = yield* stack.deploy(
34 Effect.gen(function* () {
35 const site = yield* Hetzner.Website.StaticSite("Blog", {
36 cwd,
37 command: "bash build.sh",
38 outdir: "dist",
39 });
40 return { site };
41 }),
42 );
43
44 const url = deployed.site.url;
45 expect(url).toMatch(/^http:\/\/(localhost|127\.0\.0\.1):\d+\/?$/);
46 expect(deployed.site.service).toBeUndefined();
47 expect(deployed.site.server).toBeUndefined();
48
49 yield* expectUrlContains(`${url}/`, "StaticSite fixture v1", {
50 timeout: "90 seconds",
51 label: "dev staticsite index",
52 });
53
54 yield* stack.destroy();
55 }),
56 { timeout: 120_000 },
57 );
58 },
59);