Skip to content

Commit bd4ec16

Browse files
committed
bump deps, clean up spec
1 parent 5d5c9fa commit bd4ec16

3 files changed

Lines changed: 9 additions & 33 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ jobs:
3030
RAILWAY_SERVICE_NAME: ${{ vars.RAILWAY_SERVICE_NAME }}
3131
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
3232
steps:
33-
- uses: actions/checkout@v4
33+
- uses: actions/checkout@v6
3434

3535
- name: Set up Node
36-
uses: actions/setup-node@v4
36+
uses: actions/setup-node@v6
3737
with:
3838
node-version: "22"
3939

@@ -76,10 +76,10 @@ jobs:
7676
AWS_REGION: ${{ vars.AWS_REGION }}
7777
BYTESIZED_CAFE_API_URL: ${{ vars.BYTESIZED_CAFE_API_URL }}
7878
steps:
79-
- uses: actions/checkout@v4
79+
- uses: actions/checkout@v6
8080

8181
- name: Set up just
82-
uses: extractions/setup-just@v3
82+
uses: extractions/setup-just@v4
8383

8484
- name: Validate site API URL
8585
run: |
@@ -101,7 +101,7 @@ jobs:
101101
target: wasm32-unknown-wasip1
102102

103103
- name: Configure AWS credentials
104-
uses: aws-actions/configure-aws-credentials@v4
104+
uses: aws-actions/configure-aws-credentials@v6
105105
with:
106106
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
107107
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

.github/workflows/validate.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ jobs:
1313
permissions:
1414
contents: read
1515
steps:
16-
- uses: actions/checkout@v4
16+
- uses: actions/checkout@v6
1717

1818
- name: Set up just
19-
uses: extractions/setup-just@v3
19+
uses: extractions/setup-just@v4
2020

2121
- name: Validate Docker and workflow YAML
2222
run: just validate-deployment

SPEC.md

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Spec: SwiftWASM + Hummingbird + S3 Image Delivery
1+
# Spec: bytesized.co - OpenAI Image Generation using SwiftWASM + Hummingbird
22

33
## 1. Objective
44
Implement a web app where:
@@ -39,16 +39,11 @@ Implement a web app where:
3939
- The `BytesizedCafe` SwiftWASM package is built into the repo-root `bytesized-cafe-app/` directory.
4040
- The site generator publishes that directory at `/bytesized-cafe-app/`.
4141
- Published asset paths must preserve the generated nested package layout, including `/bytesized-cafe-app/platforms/browser.js`.
42-
- The `BytesizedCafe` package declares macOS 13 or newer for host-side package resolution because its Parcel dependency requires that minimum deployment target; the browser app itself is still built through the installed WebAssembly Swift SDK.
4342

4443
## 3. S3 Design
4544

4645
### 3.1 Canonical Public Origin
47-
The backend derives the public image origin from `GENERATED_IMAGES_BUCKET` and `AWS_REGION` as:
48-
49-
`https://<generated-images-bucket>.s3.<region>.amazonaws.com`
50-
51-
Do not use the S3 website endpoint for generated image URLs.
46+
The backend derives the public image origin from `GENERATED_IMAGES_BUCKET` and `AWS_REGION` as: `https://<generated-images-bucket>.s3.<region>.amazonaws.com`
5247

5348
### 3.2 Bucket Access Model
5449
- Keep S3 Object Ownership set to `Bucket owner enforced`.
@@ -151,7 +146,6 @@ Rules:
151146
- Instruct the model to prefer specific, visually distinct local dishes over generic national defaults, and to avoid repeatedly defaulting to globally common fast food unless it is genuinely the random choice.
152147
- Fall back to the same prompt structure scoped to somewhere in the world when the client IP or country cannot be resolved.
153148
- Call the OpenAI image generation API with model `gpt-image-1.5`.
154-
- Allow up to 120 seconds for the OpenAI image generation request to complete before failing the server request.
155149
- Upload the PNG to the generated image key used for the dated generation pool.
156150
- Upload the same PNG to the stable page-cache key.
157151
- Return the page-cache `url`.
@@ -163,13 +157,11 @@ Rules:
163157

164158
## 7. Frontend Behavior
165159
- Show a loading placeholder immediately.
166-
- Install the JavaScript event loop executor before spawning async startup work.
167160
- Read page context from the mount element.
168161
- If session storage contains a URL for the same page path and page type, reuse that URL and skip the API call.
169162
- Otherwise, start a single `POST` request to the configured API URL.
170163
- When the request succeeds, swap the placeholder image source to the returned `url`.
171164
- Persist the returned image URL in session storage keyed to the current page so the next same-session visit of that page can reuse it.
172-
- Do not poll.
173165

174166
## 8. Environment Variables
175167

@@ -184,11 +176,7 @@ Rules:
184176
- `HOST`
185177
- `PORT`
186178

187-
The AWS values may also be supplied through another AWS SDK credential-chain source, but Railway deployment should provide explicit environment variables or equivalent secret-backed injection.
188-
The backend should load these values through one shared environment model used by both the generation service configuration and server bind configuration.
189-
The backend environment model should read process environment values through `apple/swift-configuration`.
190179
Local repo tooling may provide `BACKEND_HOST` and `BACKEND_PORT` as aliases for the backend runtime `HOST` and `PORT` values.
191-
Backend request validation, environment validation, and terminal upstream failures should use one shared `CoreError` enum in the `Core` module.
192180

193181
### 8.2 Site Build
194182
- `BYTESIZED_CAFE_API_URL`
@@ -207,41 +195,29 @@ The implementation is considered complete when:
207195
- Fresh generations include a country slug suffix in the image key when the request country is known.
208196
- When the daily budget is exhausted, fallback selection prefers existing images whose keys match the current request country and otherwise falls back to any existing image.
209197
- The backend persists deterministic per-page cache keys separately from the dated generation pool.
210-
- No DynamoDB, SQS, DLQ, or status-object flow is required by the active path.
211198

212199
## 10. Deployment
213200

214201
### 10.1 Container Build
215202
- The backend container image is built from `Backend/` using the checked-in `Backend/Dockerfile`.
216-
- The backend Docker build context includes `Tests/` alongside `Package.swift`, `Package.resolved`, and `Sources/` so SwiftPM can validate the package graph while building the `Server` executable.
217203
- The checked-in `Backend/railway.toml` codifies the Railway deploy settings that should live in source control, currently the Dockerfile builder and `/health` healthcheck.
218-
- The checked-in `Scripts/sync-github-actions-config.sh` script codifies how overlapping GitHub Actions repository variables and secrets can be synchronized from the local `.ENV` file.
219-
- The checked-in `Scripts/sync-railway-backend-variables.sh` script codifies how GitHub Actions synchronizes backend runtime variables into Railway before deployment, requiring `RAILWAY_PROJECT_ID` in the environment because `railway variable set` resolves project context from the environment rather than a `--project` flag.
220204
- The deployable product is the `Server` executable.
221205
- Railway builds and runs the production image from GitHub pushes, targeting the backend service with `railway up Backend --ci --path-as-root`.
222-
- The runtime base image remains `swift:6.2.4-bookworm-slim`.
223206
- Deployment config changes are validated with `just validate-deployment`, which delegates to `./Scripts/validate-deployment-config.sh` to build the Docker image and validate workflow YAML parsing.
224207

225208
### 10.2 Railway Infrastructure
226209
- Railway hosts the public backend service, injects runtime environment variables, and exposes a healthchecked HTTPS endpoint for the `Server` container.
227-
- The backend Railway service can be created as an empty service because GitHub Actions uploads `Backend/` directly during deployment.
228210
- The Railway service should define a stable custom domain so the static site can build against a fixed `BYTESIZED_CAFE_API_URL`.
229211
- The GitHub Actions workflow under `.github/workflows/deploy.yml` is the production deployment path and is intended to run on pushes to the primary deployment branch.
230212
- The backend deploy job authenticates with a Railway project token, synchronizes the backend runtime variables into Railway, and deploys the `Backend/` directory directly to the configured Railway project, environment, and service.
231213
- Railway service-level GitHub autodeploy should be disabled when the GitHub Actions workflow is the active deployment path, to avoid duplicate backend deployments from the same push.
232214
- GitHub Actions repository variables and secrets are the source of truth for the backend runtime variables `GENERATED_IMAGES_BUCKET`, `OPENAI_API_KEY`, `OPENAI_IMAGE_MODEL`, `IMAGE_GEN_PREFIX`, `AWS_REGION`, `AWS_ACCESS_KEY_ID`, and `AWS_SECRET_ACCESS_KEY`.
233-
- The overlapping GitHub Actions repository variables and secrets can be seeded from the local `.ENV` file with `Scripts/sync-github-actions-config.sh`, but deployment-only values such as `RAILWAY_PROJECT_ID`, `RAILWAY_ENVIRONMENT_NAME`, `RAILWAY_SERVICE_NAME`, `RAILWAY_TOKEN`, `BYTESIZED_CAFE_API_URL`, and `CLOUDFRONT_DISTRIBUTION_ID` remain manually managed because they do not belong in the local development env file.
234215
- The backend deploy workflow sets `HOST=0.0.0.0` and `PORT=8080` in Railway by default, unless the deploy job overrides `RAILWAY_RUNTIME_HOST` or `RAILWAY_RUNTIME_PORT`.
235-
- Secret values are synchronized with Railway through `railway variable set KEY --stdin` so they are not exposed on the command line during GitHub Actions runs.
236-
- Inline shell in the deployment and validation workflows is minimized in favor of reusable repo-root `just` recipes so the same deployment task entry points can be reused locally and in CI.
237-
- The site deploy job installs Swift 6.2.3 with `swift-actions/setup-swift@v3`, which resolves toolchains through Swiftly, installs the matching SwiftWasm SDK via `swiftwasm/setup-swiftwasm@v2.1` for `wasm32-unknown-wasip1`, and passes the resulting `swift-sdk-id` into `just wasm` so the deploy does not depend on the runner image's preinstalled Swift toolchain or SDK ordering.
238216
- The site deploy job continues to sync `Output/` to S3 using a fixed `BYTESIZED_CAFE_API_URL`.
239217
- Paginated archive links use the literal deployed object paths under `/page/<n>/index.html` because the production S3 and CloudFront setup does not rewrite clean directory URLs to nested `index.html` objects.
240218
- After the S3 sync completes, the site deploy job invalidates the production CloudFront distribution with `CLOUDFRONT_DISTRIBUTION_ID` for `/`, `/index.html`, `/page/*`, `/posts/*`, `/feed.rss`, `/bytesized-cafe-app/*`, `/css/*`, `/images/*`, and `/fonts/*`.
241-
- The site deploy sync no longer owns generated images, because they live in a separate generated-images bucket from the static site bucket.
242219

243220
## 11. Local Development
244221
- A repo-root `justfile` provides the primary entry point for common local tasks such as `just wasm`, `just site`, `just site-local`, `just backend`, and `just local`, along with deployment-oriented recipes like `just site-release`, `just site-deploy`, and `just validate-deployment`.
245222
- `Scripts/run-local.sh` provides a one-command local stack for development and opens the local site in the default browser after the backend and static site server are ready.
246223
- The script rebuilds the `BytesizedCafe` SwiftWASM bundle, regenerates the site with `BYTESIZED_CAFE_API_URL` pointed at a localhost backend, prebuilds the backend to avoid counting SwiftPM compilation against the startup timeout, starts the Hummingbird server, and serves `Output/` over a local static HTTP server.
247-
- The `justfile` and local-run script read a repo-root `.ENV` file by default when one exists, while still allowing direct shell environment configuration and host or port overrides for the site and backend.

0 commit comments

Comments
 (0)