diff --git a/.dockerignore b/.dockerignore index c6386e0..ad8a234 100644 --- a/.dockerignore +++ b/.dockerignore @@ -10,6 +10,5 @@ core/pkg server/data docs coredocs -vendor *.log *.local diff --git a/Dockerfile b/Dockerfile index 878b9ed..5fa184a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,11 +18,11 @@ RUN toolchain="$(sed -n 's/^channel = "\([^"]*\)"/\1/p' rust-toolchain.toml)" \ COPY package.json package-lock.json ./ COPY core/package.json ./core/package.json -COPY addons/handles/package.json ./addons/handles/package.json +COPY addons ./addons +COPY vendor ./vendor RUN --mount=type=cache,target=/root/.npm npm ci --include=dev COPY core ./core -COPY addons/handles ./addons/handles COPY server/build.mjs ./server/build.mjs RUN --mount=type=cache,target=/src/target mkdir -p /out \ && wasm-pack build core --target web --out-dir /out/pkg --release \ @@ -42,6 +42,9 @@ RUN --mount=type=cache,target=/go/pkg/mod \ FROM debian:bookworm-slim AS runtime +ARG YAWN_DEPLOYED_AT="" +ARG YAWN_DEPLOY_COMMIT_MESSAGE="" + RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates curl \ && rm -rf /var/lib/apt/lists/* \ @@ -58,7 +61,9 @@ COPY --from=package-builder --chown=yawn:yawn /src/node_modules/monaco-editor/mi ENV PORT=5002 \ YAWN_ROOT=/app \ YAWN_PACKAGES=/app/packages \ - YAWN_DATABASE=/data/yawn.db + YAWN_DATABASE=/data/yawn.db \ + YAWN_DEPLOYED_AT="${YAWN_DEPLOYED_AT}" \ + YAWN_DEPLOY_COMMIT_MESSAGE="${YAWN_DEPLOY_COMMIT_MESSAGE}" USER yawn:yawn VOLUME ["/data"] diff --git a/server/app.go b/server/app.go index da174a3..f6b7498 100644 --- a/server/app.go +++ b/server/app.go @@ -13,6 +13,7 @@ import ( "path" "strconv" "strings" + "time" ) //go:embed web @@ -40,6 +41,13 @@ func newApplication(store *playgroundStore, packages map[string]memoryAsset, mon if err != nil { return nil, err } + if name == "home.html" { + logMessage, err := json.Marshal(deploymentLogMessage()) + if err != nil { + return nil, err + } + content = bytes.Replace(content, []byte("__YAWN_DEPLOYMENT_LOG__"), logMessage, 1) + } pages[name] = content } return &application{ @@ -51,6 +59,22 @@ func newApplication(store *playgroundStore, packages map[string]memoryAsset, mon }, nil } +func deploymentLogMessage() string { + deployedAt := "unknown" + if value := os.Getenv("YAWN_DEPLOYED_AT"); value != "" { + deployedAt = value + if parsed, err := time.Parse(time.RFC3339, value); err == nil { + ist := time.FixedZone("IST", 5*60*60+30*60) + deployedAt = parsed.In(ist).Format("2 January 2006, 03:04:05 PM MST") + } + } + commitMessage := strings.TrimSpace(os.Getenv("YAWN_DEPLOY_COMMIT_MESSAGE")) + if commitMessage == "" { + commitMessage = "unknown" + } + return fmt.Sprintf("Yawn deployed at %s\nLatest commit: %s", deployedAt, commitMessage) +} + func (app *application) routes() http.Handler { mux := http.NewServeMux() mux.HandleFunc("/healthz", app.health) diff --git a/server/app_test.go b/server/app_test.go index 7aab904..5a0bc13 100644 --- a/server/app_test.go +++ b/server/app_test.go @@ -68,6 +68,25 @@ func TestHealth(t *testing.T) { } } +func TestHomeLogsDeploymentMetadata(t *testing.T) { + t.Setenv("YAWN_DEPLOYED_AT", "2026-08-24T18:30:00Z") + t.Setenv("YAWN_DEPLOY_COMMIT_MESSAGE", "Fix Docker deployment") + request := httptest.NewRequest(http.MethodGet, "/", nil) + response := httptest.NewRecorder() + testApplication(t).routes().ServeHTTP(response, request) + if response.Code != http.StatusOK { + t.Fatalf("status = %d", response.Code) + } + for _, expected := range []string{ + `console.log("Yawn deployed at 25 August 2026, 12:00:00 AM IST\nLatest commit: Fix Docker deployment")`, + "Yawn", + } { + if !bytes.Contains(response.Body.Bytes(), []byte(expected)) { + t.Fatalf("home page does not contain %q", expected) + } + } +} + func TestPlaygroundStoreMigratesLoadouts(t *testing.T) { path := filepath.Join(t.TempDir(), "legacy.db") database, err := sql.Open("sqlite3", path) diff --git a/server/deploy-docker.sh b/server/deploy-docker.sh index b646545..c1b11e4 100755 --- a/server/deploy-docker.sh +++ b/server/deploy-docker.sh @@ -50,8 +50,14 @@ if [[ "$(git rev-parse HEAD)" != "$fetched" ]]; then exit 1 fi +deployed_at="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" +commit_message="$(git log -1 --format=%s)" + printf 'Building the production image...\n' -"${compose[@]}" build --pull yawn +"${compose[@]}" build --pull \ + --build-arg "YAWN_DEPLOYED_AT=$deployed_at" \ + --build-arg "YAWN_DEPLOY_COMMIT_MESSAGE=$commit_message" \ + yawn "${compose[@]}" up -d --remove-orphans yawn container="$("${compose[@]}" ps -q yawn)" diff --git a/server/web/home.html b/server/web/home.html index 1abefa3..3f8ec54 100644 --- a/server/web/home.html +++ b/server/web/home.html @@ -13,6 +13,9 @@ <link rel="stylesheet" href="/assets/site.css" /> <link rel="stylesheet" href="/assets/theme.css" /> <script type="module" src="/assets/site.js"></script> + <script> + console.log(__YAWN_DEPLOYMENT_LOG__); + </script> </head> <body> <header class="site-header">