Skip to content

CI/CD

At the end you will know every automated pipeline this project runs, how they chain, and why they are split the way they are. All of them authenticate with repo-native tokens only — no stored secrets.

The whole chain, left to right

flowchart LR
    subgraph T[Triggers]
        P1[push to main<br/>agent code paths]
        P2[push to main<br/>docs paths]
        C1[cron 11:00 UTC]
        C2[cron 11:45 UTC]
    end

    C1 --> WT[job-scout<br/>daily trends]
    P1 --> WI[job-scout<br/>image]
    P2 --> WD[job-scout<br/>docs]
    C2 --> WD

    WT -->|commit + tag<br/>trends/YYYYMMDD| DATA[(data/ats_raw_trends.parquet<br/>public, facts only)]
    WI --> GHCR[(ghcr.io/senthilsweb/job-scout<br/>amd64 + arm64)]
    DATA -.->|read at build time| WD

    WD -->|mkdocs build --strict| SITE
    subgraph SITE[GitHub Pages]
        W[/wiki pages/]
        TR[/trends/ — daily dashboard<br/>jd none, no targets/]
        CO[/console/ — DuckDB browser/]
    end

The three workflows

job-scout daily trends (cron 11:00 UTC + manual). Fetches every configured job board, exports the facts-only parquet, overwrites the one canonical data/ats_raw_trends.parquet, and tags the commit trends/YYYYMMDD so any day stays fetchable by ref. Needs only the default GITHUB_TOKEN.

job-scout image (push touching the agent + manual). Rebuilds the runtime image for amd64 and arm64 and pushes latest, sha-*, and date tags to GHCR.

job-scout docs (push touching docs/templates/console, cron 11:45 UTC, + manual). Builds the wiki with mkdocs build --strict (a broken link fails the build), then adds two live pages to the site before deploying:

  • /console/ — a copy of the DuckDB browser console.
  • /trends/ — the public dashboard, built fresh from the committed parquet with --jd none (no job-description text) and --no-targets (no role keywords; visitors pass ?roles=a,b,c).

Deployment is actions/deploy-pages with the workflow's own OIDC token — no gh-pages branch, and the built site is never committed.

Two deliberate decouplings

Data does not depend on the image. The trends workflow installs its four pip packages directly instead of running inside the Docker image — so a broken image build can never stop the daily data refresh. Two small dependency lists are the price of independent failure domains.

The chain is cron-based, not push-based. The docs site refreshes 45 minutes after the data publish by schedule, not by trigger, because GitHub deliberately stops commits made with the default GITHUB_TOKEN from firing other workflows (recursion guard). A personal access token would enable a push-chain but adds a stored credential for no real gain; worst case today is the dashboard serving yesterday's facts until the next cron.

The same pattern elsewhere

agent-job-matcher mirrors this setup with its own independent site and adds two more workflows: semantic releases from Conventional Commits and a CI-generated knowledge graph — see its Runbook.

Next: FAQ.