Compare commits
8 commits
codex/forg
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| a2c998b894 | |||
|
|
799299efca | ||
|
|
6405254e42 | ||
| 8b0ef39cdf | |||
|
|
d00a7b3b80 | ||
| da9a5a942d | |||
|
|
16c69a1065 | ||
| b087e65978 |
10 changed files with 47 additions and 35 deletions
|
|
@ -48,17 +48,20 @@ jobs:
|
||||||
deploy:
|
deploy:
|
||||||
needs: ci
|
needs: ci
|
||||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||||
runs-on: docker
|
runs-on: deploy
|
||||||
container:
|
|
||||||
image: ghcr.io/catthehacker/ubuntu:act-latest
|
|
||||||
options: --security-opt label=disable
|
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: https://data.forgejo.org/actions/checkout@v4
|
run: |
|
||||||
with:
|
if [ -d .git ]; then
|
||||||
fetch-depth: 0
|
git remote set-url origin git@git.dimensionlab.net:vince/dimensionlab-website.git
|
||||||
submodules: false
|
else
|
||||||
|
git init
|
||||||
|
git remote add origin git@git.dimensionlab.net:vince/dimensionlab-website.git
|
||||||
|
fi
|
||||||
|
git fetch --force --prune --depth=1 origin "$GITHUB_SHA"
|
||||||
|
git checkout --force --detach "$GITHUB_SHA"
|
||||||
|
git clean -ffdx
|
||||||
|
|
||||||
- name: Initialize submodules
|
- name: Initialize submodules
|
||||||
run: |
|
run: |
|
||||||
|
|
@ -67,13 +70,14 @@ jobs:
|
||||||
|
|
||||||
- name: Verify Podman deployment socket
|
- name: Verify Podman deployment socket
|
||||||
run: |
|
run: |
|
||||||
timeout 15s docker version
|
command -v podman
|
||||||
unit="$(timeout 15s docker inspect dimensionlab-website --format '{{ index .Config.Labels "PODMAN_SYSTEMD_UNIT" }}')"
|
command -v systemctl
|
||||||
|
unit="$(timeout 15s podman inspect dimensionlab-website --format '{{ index .Config.Labels "PODMAN_SYSTEMD_UNIT" }}')"
|
||||||
test "$unit" = "dimensionlab-website.service"
|
test "$unit" = "dimensionlab-website.service"
|
||||||
|
|
||||||
- name: Deploy production website
|
- name: Deploy production website
|
||||||
env:
|
env:
|
||||||
DEPLOY_CONTAINER_CLI: docker
|
DEPLOY_CONTAINER_CLI: podman
|
||||||
DEPLOY_EVENT_NAME: ${{ github.event_name }}
|
DEPLOY_EVENT_NAME: ${{ github.event_name }}
|
||||||
DEPLOY_REF: ${{ github.ref }}
|
DEPLOY_REF: ${{ github.ref }}
|
||||||
DEPLOY_RESTART_STRATEGY: quadlet-container
|
DEPLOY_RESTART_STRATEGY: quadlet-container
|
||||||
|
|
|
||||||
24
README.md
24
README.md
|
|
@ -161,3 +161,27 @@ The env file must provide `AGENT_CONFIG_TOKEN`. Runtime defaults inside the
|
||||||
image set `HOST=0.0.0.0`, `PORT=3000`,
|
image set `HOST=0.0.0.0`, `PORT=3000`,
|
||||||
`DATABASE_URL=file:/data/dimensionlab.sqlite`, and
|
`DATABASE_URL=file:/data/dimensionlab.sqlite`, and
|
||||||
`DASHBOARD_MIGRATIONS_DIR=/repo/apps/web/drizzle`.
|
`DASHBOARD_MIGRATIONS_DIR=/repo/apps/web/drizzle`.
|
||||||
|
|
||||||
|
### Forgejo Actions Deployment
|
||||||
|
|
||||||
|
Merges to `main` run `.forgejo/workflows/dimensionlab-website.yml`. Pull
|
||||||
|
requests run check, test, and build only; the deploy job is guarded to run only
|
||||||
|
for `push` events on `refs/heads/main`.
|
||||||
|
|
||||||
|
The workflow uses two runner classes. Pull request CI runs on the containerized
|
||||||
|
`docker` runner. Production deployment runs on a separate host runner with the
|
||||||
|
`deploy:host` label so the guarded deploy script can use the user's rootless
|
||||||
|
`podman` and `systemctl --user` commands directly. The deploy job uses a
|
||||||
|
shell-only `git fetch` checkout so the host runner does not need a Node runtime
|
||||||
|
for checkout actions.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
runner:
|
||||||
|
labels:
|
||||||
|
- deploy:host
|
||||||
|
```
|
||||||
|
|
||||||
|
The deploy job also performs a host preflight against the
|
||||||
|
`dimensionlab-website.service` Podman label before it builds or restarts the
|
||||||
|
production container. Do not give the general pull request runner deployment
|
||||||
|
socket access; keep deploy privileges on the dedicated `deploy` runner.
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,6 @@ const verifiedSeedIconIds = new Set([
|
||||||
"mdi:pulse",
|
"mdi:pulse",
|
||||||
"mdi:robot-outline",
|
"mdi:robot-outline",
|
||||||
"mdi:router-network",
|
"mdi:router-network",
|
||||||
"mdi:text-box-search",
|
|
||||||
"mdi:thermometer",
|
"mdi:thermometer",
|
||||||
"mdi:web",
|
"mdi:web",
|
||||||
"mdi:weather-sunny",
|
"mdi:weather-sunny",
|
||||||
|
|
|
||||||
|
|
@ -431,14 +431,6 @@ export const dimensionLabDashboardFixture: DashboardDocument = {
|
||||||
href: "https://models.dimensionlab.net",
|
href: "https://models.dimensionlab.net",
|
||||||
datasource: uptimeMonitor(7),
|
datasource: uptimeMonitor(7),
|
||||||
}),
|
}),
|
||||||
service({
|
|
||||||
id: "prompt-registry",
|
|
||||||
label: "Prompt Registry",
|
|
||||||
description: "Shared prompts, traces, evals",
|
|
||||||
icon: "mdi:text-box-search",
|
|
||||||
href: "https://prompts.dimensionlab.net",
|
|
||||||
datasource: uptimeMonitor(20),
|
|
||||||
}),
|
|
||||||
]),
|
]),
|
||||||
group("systems", "Systems", [
|
group("systems", "Systems", [
|
||||||
service({
|
service({
|
||||||
|
|
|
||||||
|
|
@ -66,9 +66,6 @@ describe("dashboard runtime loader", () => {
|
||||||
expect(runtime.document.statusStrips[0]?.items.map((item) => item.id)).toContain(
|
expect(runtime.document.statusStrips[0]?.items.map((item) => item.id)).toContain(
|
||||||
"auto-refresh",
|
"auto-refresh",
|
||||||
);
|
);
|
||||||
expect(runtime.document.serviceGroups.flatMap((group) => group.services).map((service) => service.id)).toContain(
|
|
||||||
"prompt-registry",
|
|
||||||
);
|
|
||||||
expect(store.listRevisions()).toHaveLength(2);
|
expect(store.listRevisions()).toHaveLength(2);
|
||||||
expect(store.getActiveDashboard()?.revision.actor).toBe("initial-seed");
|
expect(store.getActiveDashboard()?.revision.actor).toBe("initial-seed");
|
||||||
});
|
});
|
||||||
|
|
@ -138,13 +135,5 @@ function olderDimensionLabSeed() {
|
||||||
...strip,
|
...strip,
|
||||||
items: strip.items.filter((item) => item.id !== "auto-refresh"),
|
items: strip.items.filter((item) => item.id !== "auto-refresh"),
|
||||||
}));
|
}));
|
||||||
document.serviceGroups = document.serviceGroups.map((group) =>
|
|
||||||
group.id === "ai-automation"
|
|
||||||
? {
|
|
||||||
...group,
|
|
||||||
services: group.services.filter((service) => service.id !== "prompt-registry"),
|
|
||||||
}
|
|
||||||
: group,
|
|
||||||
);
|
|
||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -275,10 +275,15 @@ describe("workspace boundaries", () => {
|
||||||
expect(workflow).toContain("bun run test");
|
expect(workflow).toContain("bun run test");
|
||||||
expect(workflow).toContain("bun run build");
|
expect(workflow).toContain("bun run build");
|
||||||
expect(workflow).toContain("needs: ci");
|
expect(workflow).toContain("needs: ci");
|
||||||
expect(workflow).toContain("options: --security-opt label=disable");
|
expect(workflow).toContain("runs-on: deploy");
|
||||||
expect(workflow).toContain("github.event_name == 'push'");
|
expect(workflow).toContain("github.event_name == 'push'");
|
||||||
expect(workflow).toContain("github.ref == 'refs/heads/main'");
|
expect(workflow).toContain("github.ref == 'refs/heads/main'");
|
||||||
expect(workflow).toContain("docker inspect dimensionlab-website");
|
expect(workflow).toContain(
|
||||||
|
"git remote add origin git@git.dimensionlab.net:vince/dimensionlab-website.git",
|
||||||
|
);
|
||||||
|
expect(workflow).toContain('git fetch --force --prune --depth=1 origin "$GITHUB_SHA"');
|
||||||
|
expect(workflow).toContain("podman inspect dimensionlab-website");
|
||||||
|
expect(workflow).toContain("DEPLOY_CONTAINER_CLI: podman");
|
||||||
expect(workflow).toContain("PODMAN_SYSTEMD_UNIT");
|
expect(workflow).toContain("PODMAN_SYSTEMD_UNIT");
|
||||||
expect(workflow).toContain("scripts/deploy-dimensionlab-website.sh");
|
expect(workflow).toContain("scripts/deploy-dimensionlab-website.sh");
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ const linkedServiceIds = [
|
||||||
"open-webui",
|
"open-webui",
|
||||||
"comfyui",
|
"comfyui",
|
||||||
"models",
|
"models",
|
||||||
"prompt-registry",
|
|
||||||
"adminer",
|
"adminer",
|
||||||
"assistant",
|
"assistant",
|
||||||
"suna",
|
"suna",
|
||||||
|
|
@ -104,7 +103,7 @@ test.describe("dashboard page QA gate", () => {
|
||||||
expect(metrics.runtimeBottom).toBeLessThanOrEqual(956);
|
expect(metrics.runtimeBottom).toBeLessThanOrEqual(956);
|
||||||
expect(metrics.footerBottom).toBeLessThanOrEqual(956);
|
expect(metrics.footerBottom).toBeLessThanOrEqual(956);
|
||||||
expect(metrics.telemetryCardCount).toBe(16);
|
expect(metrics.telemetryCardCount).toBe(16);
|
||||||
expect(metrics.serviceRowCount).toBe(28);
|
expect(metrics.serviceRowCount).toBe(27);
|
||||||
expect(metrics.footerCellCount).toBe(5);
|
expect(metrics.footerCellCount).toBe(5);
|
||||||
expect(metrics.clippedItems).toEqual([]);
|
expect(metrics.clippedItems).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 304 KiB After Width: | Height: | Size: 301 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 454 KiB After Width: | Height: | Size: 451 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 309 KiB After Width: | Height: | Size: 302 KiB |
Loading…
Add table
Add a link
Reference in a new issue