Something went wrong. Try again.
A lexicon-driven AppView for ATProto.
Something went wrong. Try again.
YAML
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588name: CI
on: push: branches: [main, dev, ci/merge-workflows] pull_request: branches: [main, dev, ci/merge-workflows] release: types: [published] delete:
env: SQLX_OFFLINE: true
jobs: # --------------------------------------------------------------------------- # Path detection — determines which job groups should run. # Required because workflow-level `paths` filters can't vary per job. # --------------------------------------------------------------------------- changes: if: github.event_name == 'push' || github.event_name == 'pull_request' runs-on: depot-ubuntu-24.04 outputs: server: ${{ steps.filter.outputs.server }} sdk: ${{ steps.filter.outputs.sdk }} postgres: ${{ steps.filter.outputs.postgres }} steps: - name: Checkout repository uses: actions/checkout@v6
- name: Detect changed paths id: filter uses: dorny/paths-filter@v3 with: filters: | server: - '**' - '!packages/**' - '!.github/workflows/merge-main-to-dev.yml' sdk: - 'packages/oauth-client/**' - 'packages/oauth-client-browser/**' - 'packages/oauth-client-node/**' - 'packages/lex-agent/**' postgres: - 'docker/Dockerfile.postgres' - 'docker/init-databases.sh'
# --------------------------------------------------------------------------- # Server — unit tests, e2e tests, frontend build, lint # --------------------------------------------------------------------------- unit-tests: needs: changes if: needs.changes.outputs.server == 'true' runs-on: depot-ubuntu-24.04 steps: - name: Checkout repository uses: actions/checkout@v6
- name: Cache cargo uses: actions/cache@v5 with: path: | ~/.cargo/registry ~/.cargo/git target key: cargo-${{ runner.os }}-${{ hashFiles('Cargo.lock') }} restore-keys: | cargo-${{ runner.os }}-
- name: Run unit tests run: cargo test --lib
e2e-tests: needs: changes if: needs.changes.outputs.server == 'true' runs-on: depot-ubuntu-24.04 services: postgres: image: postgres:16-alpine env: POSTGRES_USER: happyview POSTGRES_PASSWORD: happyview POSTGRES_DB: happyview_test ports: - 5432:5432 options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - name: Checkout repository uses: actions/checkout@v6
- name: Cache cargo uses: actions/cache@v5 with: path: | ~/.cargo/registry ~/.cargo/git target key: cargo-${{ runner.os }}-${{ hashFiles('Cargo.lock') }} restore-keys: | cargo-${{ runner.os }}-
- name: Add WASM target run: rustup target add wasm32-unknown-unknown
- name: Build test plugin run: cargo build --manifest-path tests/fixtures/test_plugin/Cargo.toml --target wasm32-unknown-unknown --release
- name: Run e2e tests env: TEST_DATABASE_URL: postgres://happyview:happyview@localhost:5432/happyview_test run: cargo test --tests
frontend: needs: changes if: needs.changes.outputs.server == 'true' runs-on: depot-ubuntu-24.04 steps: - name: Checkout repository uses: actions/checkout@v6
- name: Setup Node.js uses: actions/setup-node@v6 with: node-version: 24
- name: Build frontend working-directory: web run: npm ci && npm run build
lint: needs: changes if: needs.changes.outputs.server == 'true' runs-on: depot-ubuntu-24.04 steps: - name: Checkout repository uses: actions/checkout@v6
- name: Cache cargo dependencies uses: actions/cache@v5 with: path: | ~/.cargo/registry ~/.cargo/git key: cargo-deps-${{ runner.os }}-${{ hashFiles('Cargo.lock') }} restore-keys: | cargo-deps-${{ runner.os }}-
- name: Check formatting run: cargo fmt -- --check
- name: Clippy run: cargo clippy --all-targets -- -D warnings
# --------------------------------------------------------------------------- # Server release # --------------------------------------------------------------------------- release: if: >- github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev') && needs.changes.outputs.server == 'true' needs: [changes, unit-tests, e2e-tests, frontend, lint] runs-on: depot-ubuntu-24.04 permissions: contents: write steps: - name: Checkout repository uses: actions/checkout@v6 with: fetch-depth: 0
- name: Setup Node.js uses: actions/setup-node@v6 with: node-version: 22
- name: Release env: GITHUB_TOKEN: ${{ secrets.DISPATCH_GH_TOKEN }} run: npx semantic-release
# --------------------------------------------------------------------------- # SDK — tests + per-package releases # --------------------------------------------------------------------------- sdk-tests: needs: changes if: needs.changes.outputs.sdk == 'true' runs-on: depot-ubuntu-24.04 steps: - name: Checkout repository uses: actions/checkout@v6
- name: Setup Bun uses: oven-sh/setup-bun@v2
- name: Install dependencies run: bun install
- name: Build SDK packages run: bun run --filter '@happyview/*' build
- name: Typecheck SDK packages run: bun run --filter '@happyview/*' typecheck
- name: Test SDK packages run: bun run --filter '@happyview/*' test
release-oauth-client: if: >- github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev') && needs.changes.outputs.sdk == 'true' needs: [changes, sdk-tests] runs-on: depot-ubuntu-24.04 permissions: contents: write steps: - name: Checkout repository uses: actions/checkout@v6 with: fetch-depth: 0
- name: Setup Bun uses: oven-sh/setup-bun@v2
- name: Setup Node.js uses: actions/setup-node@v6 with: node-version: 24
- name: Install dependencies run: bun install
- name: Build oauth-client run: bun run --filter '@happyview/oauth-client' build
- name: Configure npm auth for bun publish run: echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" > .npmrc
- name: Release oauth-client env: GITHUB_TOKEN: ${{ secrets.DISPATCH_GH_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} working-directory: packages/oauth-client run: npx semantic-release
release-oauth-client-browser: if: >- github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev') && needs.changes.outputs.sdk == 'true' needs: [changes, release-oauth-client] runs-on: depot-ubuntu-24.04 permissions: contents: write steps: - name: Checkout repository uses: actions/checkout@v6 with: fetch-depth: 0
- name: Setup Bun uses: oven-sh/setup-bun@v2
- name: Setup Node.js uses: actions/setup-node@v6 with: node-version: 24
- name: Install dependencies run: bun install
- name: Build SDK packages run: bun run --filter '@happyview/*' build
- name: Resolve workspace dependencies to published versions run: | if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then DIST_TAG="latest" else DIST_TAG="dev" fi CORE_VERSION=$(npm view @happyview/oauth-client@${DIST_TAG} version) node -e " const fs = require('fs'); const pkg = JSON.parse(fs.readFileSync('packages/oauth-client-browser/package.json', 'utf8')); if (pkg.dependencies['@happyview/oauth-client']?.startsWith('workspace:')) { pkg.dependencies['@happyview/oauth-client'] = '^${CORE_VERSION}'; fs.writeFileSync('packages/oauth-client-browser/package.json', JSON.stringify(pkg, null, 2) + '\n'); } "
- name: Configure npm auth for bun publish run: echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" > .npmrc
- name: Release oauth-client-browser env: GITHUB_TOKEN: ${{ secrets.DISPATCH_GH_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} working-directory: packages/oauth-client-browser run: npx semantic-release
release-oauth-client-node: if: >- github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev') && needs.changes.outputs.sdk == 'true' needs: [changes, release-oauth-client] runs-on: depot-ubuntu-24.04 permissions: contents: write steps: - name: Checkout repository uses: actions/checkout@v6 with: fetch-depth: 0
- name: Setup Bun uses: oven-sh/setup-bun@v2
- name: Setup Node.js uses: actions/setup-node@v6 with: node-version: 24
- name: Install dependencies run: bun install
- name: Build SDK packages run: bun run --filter '@happyview/*' build
- name: Resolve workspace dependencies to published versions run: | if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then DIST_TAG="latest" else DIST_TAG="dev" fi CORE_VERSION=$(npm view @happyview/oauth-client@${DIST_TAG} version) node -e " const fs = require('fs'); const pkg = JSON.parse(fs.readFileSync('packages/oauth-client-node/package.json', 'utf8')); if (pkg.dependencies['@happyview/oauth-client']?.startsWith('workspace:')) { pkg.dependencies['@happyview/oauth-client'] = '^${CORE_VERSION}'; fs.writeFileSync('packages/oauth-client-node/package.json', JSON.stringify(pkg, null, 2) + '\n'); } "
- name: Configure npm auth for bun publish run: echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" > .npmrc
- name: Release oauth-client-node env: GITHUB_TOKEN: ${{ secrets.DISPATCH_GH_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} working-directory: packages/oauth-client-node run: npx semantic-release
release-lex-agent: if: >- github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev') && needs.changes.outputs.sdk == 'true' needs: [changes, release-oauth-client] runs-on: depot-ubuntu-24.04 permissions: contents: write steps: - name: Checkout repository uses: actions/checkout@v6 with: fetch-depth: 0
- name: Setup Bun uses: oven-sh/setup-bun@v2
- name: Setup Node.js uses: actions/setup-node@v6 with: node-version: 24
- name: Install dependencies run: bun install
- name: Build SDK packages run: bun run --filter '@happyview/*' build
- name: Resolve workspace dependencies to published versions run: | if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then DIST_TAG="latest" else DIST_TAG="dev" fi CORE_VERSION=$(npm view @happyview/oauth-client@${DIST_TAG} version) node -e " const fs = require('fs'); const pkg = JSON.parse(fs.readFileSync('packages/lex-agent/package.json', 'utf8')); if (pkg.dependencies['@happyview/oauth-client']?.startsWith('workspace:')) { pkg.dependencies['@happyview/oauth-client'] = '^${CORE_VERSION}'; fs.writeFileSync('packages/lex-agent/package.json', JSON.stringify(pkg, null, 2) + '\n'); } "
- name: Configure npm auth for bun publish run: echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" > .npmrc
- name: Release lex-agent env: GITHUB_TOKEN: ${{ secrets.DISPATCH_GH_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} working-directory: packages/lex-agent run: npx semantic-release
# --------------------------------------------------------------------------- # Docker — main app image (triggered by GitHub release) # --------------------------------------------------------------------------- docker: if: github.event_name == 'release' && startsWith(github.event.release.tag_name, 'v') runs-on: ${{ matrix.runs-on }} permissions: contents: read packages: write id-token: write strategy: fail-fast: false matrix: include: - platform: linux/amd64 runs-on: depot-ubuntu-24.04 - platform: linux/arm64 runs-on: depot-ubuntu-24.04-arm env: GHCR_IMAGE: ghcr.io/${{ github.repository }} ATCR_IMAGE: atcr.io/${{ secrets.ATCR_NAMESPACE }}/happyview steps: - name: Checkout repository uses: actions/checkout@v6
- name: Set up Docker Buildx uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }}
# TODO: Re-enable once ATCR rate limit issue is resolved # - name: Log in to ATCR # uses: docker/login-action@v3 # with: # registry: atcr.io # username: ${{ secrets.ATCR_USERNAME }} # password: ${{ secrets.ATCR_PASSWORD }}
- name: Extract GHCR metadata id: meta-ghcr uses: docker/metadata-action@v5 with: images: ${{ env.GHCR_IMAGE }} tags: | type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} type=sha
# TODO: Re-enable once ATCR rate limit issue is resolved # - name: Extract ATCR metadata # id: meta-atcr # uses: docker/metadata-action@v5 # with: # images: ${{ env.ATCR_IMAGE }} # tags: | # type=semver,pattern={{version}} # type=semver,pattern={{major}}.{{minor}} # type=semver,pattern={{major}} # type=sha
- name: Build and push to GHCR by digest id: build uses: docker/build-push-action@v5 with: context: . platforms: ${{ matrix.platform }} labels: ${{ steps.meta-ghcr.outputs.labels }} build-args: | HAPPYVIEW_VERSION=${{ github.event.release.tag_name }} cache-from: type=gha,scope=build-${{ matrix.platform }} cache-to: type=gha,scope=build-${{ matrix.platform }},mode=max,ignore-error=true outputs: type=image,"name=${{ env.GHCR_IMAGE }}",push-by-digest=true,name-canonical=true,push=true
# TODO: Re-enable once ATCR rate limit issue is resolved # - name: Push to ATCR by digest # id: build-atcr # continue-on-error: true # uses: docker/build-push-action@v5 # with: # context: . # platforms: ${{ matrix.platform }} # labels: ${{ steps.meta-atcr.outputs.labels }} # build-args: | # HAPPYVIEW_VERSION=${{ github.event.release.tag_name }} # cache-from: type=gha,scope=build-${{ matrix.platform }} # outputs: type=image,"name=${{ env.ATCR_IMAGE }}",push-by-digest=true,name-canonical=true,push=true
- name: Create GHCR manifest run: | GHCR_TAGS=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< '${{ steps.meta-ghcr.outputs.json }}') docker buildx imagetools create --append $GHCR_TAGS \ ${{ env.GHCR_IMAGE }}@${{ steps.build.outputs.digest }} 2>/dev/null || \ docker buildx imagetools create $GHCR_TAGS \ ${{ env.GHCR_IMAGE }}@${{ steps.build.outputs.digest }}
# TODO: Re-enable once ATCR rate limit issue is resolved # - name: Create ATCR manifest # if: steps.build-atcr.outcome == 'success' # continue-on-error: true # run: | # ATCR_TAGS=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< '${{ steps.meta-atcr.outputs.json }}') # if [ -n "$ATCR_TAGS" ]; then # docker buildx imagetools create --append $ATCR_TAGS \ # ${{ env.ATCR_IMAGE }}@${{ steps.build-atcr.outputs.digest }} 2>/dev/null || \ # docker buildx imagetools create $ATCR_TAGS \ # ${{ env.ATCR_IMAGE }}@${{ steps.build-atcr.outputs.digest }} # fi
# --------------------------------------------------------------------------- # Docker — Postgres image (only when Postgres Docker files change) # --------------------------------------------------------------------------- docker-postgres: needs: changes if: >- github.event_name == 'push' && needs.changes.outputs.postgres == 'true' runs-on: depot-ubuntu-24.04 permissions: contents: read packages: write env: GHCR_POSTGRES_IMAGE: ghcr.io/${{ github.repository }}-postgres steps: - name: Checkout repository uses: actions/checkout@v6
- name: Set up Docker Buildx uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push uses: docker/build-push-action@v5 with: context: docker file: docker/Dockerfile.postgres push: true tags: ${{ env.GHCR_POSTGRES_IMAGE }}:latest cache-from: type=gha,scope=postgres cache-to: type=gha,scope=postgres,mode=max,ignore-error=true
# --------------------------------------------------------------------------- # Mirror to Tangled # --------------------------------------------------------------------------- mirror: if: github.event_name == 'push' || github.event_name == 'delete' runs-on: depot-ubuntu-24.04 steps: - uses: actions/checkout@v6 with: fetch-depth: 0
- uses: yesolutions/mirror-action@master with: REMOTE: "git@tangled.org:gamesgamesgamesgames.games/happyview" GIT_SSH_PRIVATE_KEY: ${{ secrets.TANGLED_SSH_PRIVATE_KEY }} GIT_SSH_NO_VERIFY_HOST: "true"