~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

7
104 lines · 5.4 KB Raw History
# The pages used as people use them, as `just e2e` runs them: in Chromium,
# logging in through the PDS's own approval page, then every write the
# pages make, each read back on the page and from the PDS
# (harness/e2e/flows.spec.mjs), over a world seeded for the run as the
# shots' is. Then a private repository's, over another on the spaces
# alpha, each read back on the page and from its space, and as not there
# to anyone else (private.spec.mjs). The shots show what the pages draw;
# this, that what they do lands. Each flow that fails leaves the page as
# it was then among the check's outputs, as a picture.
#
# Node, the packages, Chromium, the libraries it needs, the alpha and the
# build are kept between runs, as main's runs leave them: nothing is fetched again
# until what it is made from changes.
image: rust:1.98
# Every push to main, and pulls into it or a feature/ branch, at their
# heads merged with their base, that change the pages, the server and
# client they log in to and write through, the world and harness they run
# over, or this file. A pull changing none passes at once, noted as
# skipped.
on:
  push: {refs: [refs/heads/main]}
  pull:
    base: [refs/heads/main, refs/heads/feature/*]
    paths: [web/**, lexicons/**, crates/knotless/**, crates/knotless-serve/**, crates/knotless-mcp/**, Cargo.toml, Cargo.lock, harness/e2e/**, harness/shots/world.mjs, harness/shots/fixture/**, harness/pds.mjs, harness/tls-proxy.mjs, harness/package.json, harness/package-lock.json, .knotless/workflows/e2e.yml, .knotless/uses.lock]
cache: [target, /usr/local/cargo/registry, /usr/local/rustup, /opt/node, /opt/browsers, /opt/chromium-debs, /opt/atproto, web/node_modules, harness/node_modules]
env:
  PLAYWRIGHT_BROWSERS_PATH: /opt/browsers
  # The spaces alpha the private flows run over, as test.yml pins it: the
  # two move together.
  ATPROTO_COMMIT: 11c5d98cd50261c5e1201fedc5c6c05a7b8d1ccf
  ALPHA_BUILD: "2"
steps:
  - uses: chadtmiller.com/steps/node@1
    with: {version: 24.22.1}
  - uses: chadtmiller.com/steps/npm-ci@1
    name: web
    with: {dir: web}
  - uses: chadtmiller.com/steps/npm-ci@1
    name: harness
    with: {dir: harness}
  - name: chromium
    run: |
      export PATH=/opt/node/bin:$PATH
      cd harness
      # The browser, into /opt/browsers once for each Playwright version.
      npx playwright install chromium
      # The libraries it needs, which `install-deps` would fetch with apt on
      # every run: their .debs are kept, fetched again only when this
      # Playwright or this Debian asks for others, and installed offline.
      pkgs=$(npx playwright install-deps --dry-run chromium | sed -n "s/.*--no-install-recommends \([^\"']*\).*/\1/p")
      [ -n "$pkgs" ] || { echo "no packages in: $(npx playwright install-deps --dry-run chromium)"; exit 1; }
      debs=/opt/chromium-debs
      want="$(. /etc/os-release && echo "$VERSION_ID") $pkgs"
      if [ "$(cat $debs/.want 2>/dev/null)" != "$want" ]; then
        rm -rf "${debs:?}"/* && mkdir -p $debs/partial
        apt-get update -qq
        apt-get install -y -qq --no-install-recommends --download-only -o Dir::Cache::archives=$debs $pkgs
        echo "$want" > $debs/.want
      fi
      dpkg -i $debs/*.deb > /dev/null
  - name: spaces alpha
    run: |
      [ "$(cat /opt/atproto/.built 2>/dev/null)" = "$ATPROTO_COMMIT $ALPHA_BUILD" ] && exit 0
      export PATH=/opt/node/bin:$PATH COREPACK_ENABLE_DOWNLOAD_PROMPT=0 COREPACK_HOME=/opt/atproto/.corepack
      find /opt/atproto -mindepth 1 -delete
      cd /opt/atproto
      git init -q . && git fetch -q --depth 1 https://github.com/bluesky-social/atproto.git "$ATPROTO_COMMIT" && git checkout -q FETCH_HEAD
      mkdir .bin && corepack enable --install-directory /opt/atproto/.bin
      export PATH=/opt/atproto/.bin:$PATH
      pnpm install --frozen-lockfile --ignore-scripts
      pnpm run build:tooling --force
      pnpm --filter '@atproto/dev-env^...' --filter @atproto/dev-env run --if-present prebuild
      pnpm exec tsc --build packages/dev-env/tsconfig.build.json
      # The PDS serves the OAuth sign-in pages from this bundle.
      pnpm --filter @atproto/oauth-provider-ui run build:ui
      echo "$ATPROTO_COMMIT $ALPHA_BUILD" > /opt/atproto/.built
  - name: sqlite
    run: |
      # The one install script the PDS needs, which the install above
      # skips: SQLite's native module, as better-sqlite3's own script builds
      # it (a prebuilt one where there is one).
      export PATH=/opt/node/bin:$PATH
      cd "$(dirname "$(node -p "require.resolve('better-sqlite3/package.json', { paths: ['/opt/atproto/packages/pds'] })")")"
      [ -f build/Release/better_sqlite3.node ] && exit 0
      npm run install
  - name: build
    run: |
      export PATH=/opt/node/bin:$PATH
      cargo build --bins -p knotless -p knotless-serve
      cd web && npm run build
  - name: flows
    run: |
      export PATH=/opt/node/bin:$PATH
      status=0
      (cd harness && E2E=1 npx playwright test -c e2e/playwright.config.mjs) || status=$?
      # Then the private ones, over a world of their own on the alpha.
      (cd harness && KNOTLESS_DEV_ENV=/opt/atproto/packages/dev-env E2E=1 npx playwright test -c e2e/playwright.config.mjs) || status=$?
      # The page each failed flow ended on, named for the flow.
      if [ -n "${KNOTLESS_RUN_OUTPUTS:-}" ] && [ -d target/e2e ]; then
        for shot in target/e2e/*/*/test-failed-*.png; do
          [ -f "$shot" ] && cp "$shot" "$KNOTLESS_RUN_OUTPUTS/$(basename "$(dirname "$shot")").png"
        done
      fi
      exit $status