Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"groups": [
["vitest", "@cucumber/cucumber"],
":BLANK_LINE:",
":NODE:",
[":NODE:", ":BUN:"],
":BLANK_LINE:",
":PACKAGE:",
":BLANK_LINE:",
Expand Down
5 changes: 3 additions & 2 deletions jobs/__template__/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import mysql from 'mysql2/promise';

import {
afterAll,
beforeAll,
Expand All @@ -8,6 +6,9 @@ import {
expect,
test,
} from 'bun:test';

import mysql from 'mysql2/promise';

import { doSomething } from './index';

describe('__JOB_NAME__', () => {
Expand Down
8 changes: 8 additions & 0 deletions jobs/backfill-ghost-uuid/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM oven/bun:1.3.0-alpine@sha256:37e6b1cbe053939bccf6ae4507977ed957eaa6e7f275670b72ad6348e0d2c11f

WORKDIR /opt/job

COPY index.ts .

ENTRYPOINT ["bun", "run", "index.ts"]
CMD []
67 changes: 67 additions & 0 deletions jobs/backfill-ghost-uuid/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# backfill-ghost-uuid

Backfills the `ghost_uuid` field in the `sites` table by fetching the UUID from
each site's `/ghost/api/admin/site/` endpoint

For each `site` in the database without a `ghost_uuid`, this job:

1. Makes a request to `https://<site_host>/ghost/api/admin/site/`
2. Extracts the `site_uuid` from the response
3. Updates the site record in the database

Sites are processed sequentially with a 500ms delay between requests to avoid
tripping rate limits. If a request fails, the job logs a warning and continues
to the next site

## Prerequisites

- Globally available `bun`
- Globally available `docker`

## Running locally

```bash
DB_HOST=... \
DB_PORT=... \
DB_USER=... \
DB_PASSWORD=... \
DB_NAME=... \
bun run index.ts
```

## Running tests

```bash
./run-tests.sh
```

## Production deployment

Build and push the Docker image to GCP:

```bash
./gcloud-push.sh
```

## Production execution

Use the [GCP console](https://console.cloud.google.com/run/jobs/create) to setup and execute the job

Ensure the relevant environment variables are set on the job:

```text
DB_HOST
DB_PORT
DB_USER
DB_PASSWORD
DB_NAME
```

If using a socket connection, set `DB_SOCKET_PATH` instead of `DB_HOST` and `DB_PORT`

## Notes

- The job is idempotent and can be run multiple times safely
- Sites are processed sequentially to avoid tripping rate limits
- Failed requests are logged but don't stop the job from processing remaining sites
- The job is designed to be run periodically to catch any sites that failed on previous runs
10 changes: 10 additions & 0 deletions jobs/backfill-ghost-uuid/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
services:
mysql-test:
image: mysql:8.4.6@sha256:5367102acfefeaa47eb0eb57c8d4f8b96c8c14004859131eac9bbfaa62f81e34
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: backfill-ghost-uuid
ports:
- "3308:3306"
tmpfs:
- /var/lib/mysql
39 changes: 39 additions & 0 deletions jobs/backfill-ghost-uuid/gcloud-push.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash

set -euo pipefail

IMAGE_NAME="backfill-ghost-uuid-job"

PROJECT_ID=$(gcloud config get-value project 2>/dev/null)
if [ -z "$PROJECT_ID" ]; then
echo "Error: Could not determine GCP project ID"
exit 1
fi

echo ""
echo "Building and pushing to GCP..."
echo ""
echo "Project: $PROJECT_ID"
echo "Image: $IMAGE_NAME"
echo ""

echo "Building Docker image..."
echo ""
docker build --platform linux/amd64 -t "$IMAGE_NAME" .
echo ""

IMAGE_URL="gcr.io/$PROJECT_ID/$IMAGE_NAME:latest"
echo "Tagging image: $IMAGE_URL"
docker tag "$IMAGE_NAME" "$IMAGE_URL"
echo ""

echo "Pushing image to Google Container Registry..."
echo ""
docker push "$IMAGE_URL"
echo ""

echo ""
echo "Push complete!"
echo ""
echo "Built and pushed image to '$IMAGE_URL'"
echo ""
Loading