feat(compose): add Grok brand mark to Copy-prompt button (#123) #106
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Deploy the Loopany server to Fly.io (app: loopany-testing). | |
| # Remote build → no Docker needed on the runner. Migration runs on container | |
| # boot via `pnpm start` (drizzle-kit migrate && node ...), so deploy = migrate. | |
| name: Deploy (Fly) | |
| on: | |
| push: | |
| branches: [main] | |
| # Don't redeploy for changes that can't affect the server image. | |
| # (Adjust to taste — fly.toml / Dockerfile / lockfile DO affect the build.) | |
| # NOTE: no broad '**/*.md' ignore - the skill/prompt markdown under | |
| # packages/server/src/skill/ is compiled INTO the server bundle via ?raw | |
| # imports, so a prompt-only edit MUST deploy. paths-ignore has no negation; | |
| # list the doc paths explicitly instead. (Entries are OR'd: a push is | |
| # skipped only when EVERY changed file matches an ignore entry.) | |
| paths-ignore: | |
| - 'packages/daemon/**' | |
| - 'README.md' | |
| - 'AGENTS.md' | |
| - 'CLAUDE.md' | |
| - 'CONTRIBUTING.md' | |
| - 'docs/**' | |
| workflow_dispatch: {} # manual button in the Actions tab | |
| # One deploy at a time; cancel an in-flight deploy if a newer commit lands. | |
| concurrency: | |
| group: fly-deploy | |
| cancel-in-progress: true | |
| jobs: | |
| deploy: | |
| name: flyctl deploy --remote-only | |
| runs-on: ubuntu-latest | |
| # If you later add an Environment with required reviewers, set it here: | |
| # environment: production | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: superfly/flyctl-actions/setup-flyctl@master | |
| # To pin the flyctl binary for reproducible deploys, add: | |
| # with: | |
| # version: <flyctl version, e.g. 0.3.x> | |
| - name: Deploy | |
| # GIT_SHA / BUILT_AT bake the pushed commit into the image so /api/health | |
| # reports it (the smoke check below asserts the promoted image matches). | |
| run: | | |
| flyctl deploy --remote-only \ | |
| --build-arg GIT_SHA=${{ github.sha }} \ | |
| --build-arg BUILT_AT="$(date -u +%Y-%m-%dT%H:%M:%SZ)" | |
| env: | |
| FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} | |
| # Same cheap smoke as prod: confirm loopany-testing actually serves the | |
| # commit we just pushed. This is also the live proof of the version endpoint. | |
| - name: Smoke — /api/health serves the pushed SHA | |
| run: | | |
| expected='${{ github.sha }}' | |
| got='' | |
| for attempt in 1 2 3 4 5; do | |
| if body="$(curl -fsS --max-time 15 https://loopany-testing.fly.dev/api/health)"; then | |
| echo "health: $body" | |
| got="$(printf '%s' "$body" | sed -n 's/.*"sha":"\([^"]*\)".*/\1/p')" | |
| [ "$got" = "$expected" ] && break | |
| echo "health served sha=$got, want $expected (attempt $attempt) — old container likely still draining, retrying in 10s…" >&2 | |
| else | |
| echo "health not ready (attempt $attempt), retrying in 10s…" >&2 | |
| fi | |
| sleep 10 | |
| done | |
| if [ "$got" != "$expected" ]; then | |
| echo "::error::staging /api/health sha=$got but pushed sha=$expected — the deploy did not take (or /api/health never returned 2xx)." >&2 | |
| exit 1 | |
| fi | |
| echo "staging is serving $got ✔" |