diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..fa6bef6 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,9 @@ +name: PR + +on: + pull_request: + branches: [main] + +jobs: + build: + uses: purview-dev/build/.github/workflows/purview-build.yml@main diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..f156a2b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,19 @@ +name: Release + +on: + push: + branches: [main] + +# Serialize releases; the reusable workflow skips when the v{version} tag already exists. +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: false + +jobs: + release: + uses: purview-dev/build/.github/workflows/purview-release.yml@main + with: + # The site publishes no NuGet package; tag + GitHub release (with the dist zip attached) only. + release-mode: GitHubRelease + upload-artifacts: true + secrets: inherit diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml deleted file mode 100644 index 896ec45..0000000 --- a/.github/workflows/validate.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Validate - -on: - pull_request: - branches: [main] - push: - branches: [main] - workflow_dispatch: - -permissions: - contents: read - -jobs: - validate: - runs-on: ubuntu-latest - steps: - - name: Checkout - # actions/checkout v7.0.1 - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - - - name: Install Bun - # oven-sh/setup-bun v2.2.0 - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 - with: - bun-version: 1.4.2 - - - name: Install Just - # taiki-e/install-action v2.87.13 - uses: taiki-e/install-action@26e9283f268b880168bdbd2c545dfcd60ec2c6ab - with: - tool: just@1.58.0 - - # The repository is a Bun workspace: the lockfile and root `package.json` - # live here, the Astro site package lives in `src/`, and every `bun run` - # / `just` recipe delegates to `src/` (see `package.json` scripts). - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Run validation - # `just validate` runs a live data sync on fresh checkouts (no cache / - # docs mirror yet), so pass a token to avoid unauthenticated rate limits. - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: just validate diff --git a/README.md b/README.md index cce56ba..0225eee 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,7 @@ output tests. | `test` | Deterministic unit test suite | | `test-dist` | Assert built outputs (llms, sitemap, no secrets) | | `build` | Production build (runs data sync first) | +| `ci-build` | Full CI validation chain used by the shared pipeline | | `preview` | Preview the production build | | `check-assets` | Validate branding sources and generated assets | | `check-links` | Validate internal links across `dist/` | @@ -255,6 +256,25 @@ The build generates `/llms.txt`, `/llms-small.txt`, and `/llms-full.txt` the aggregated documentation. The built outputs are asserted by `tests/dist/` and `just check-generated`. +## Site versioning and releases + +The site is versioned like every other purview-dev repository. The single +source of truth is the `version` field in the root `package.json`; the footer +shows the current `v{version}` (linking to the repository's GitHub releases +page), read at build time by `src/src/lib/site-version.ts`. + +Building and release flow run through the shared +[Purview.Build](https://purview.dev/projects/build/) system as a `Web` project +(`Build:ProjectType=Web` in `purview-build.json`): the pipeline runs the root +`package.json` scripts (`bun install`, `bun run format:check`/`bun run lint`, +`bun run test`) and the `ci:build` script, which chains data sync, typecheck, +asset checks, the production build, link crawl, generated-output checks, and +built-output tests. Releasing means bumping `version` in the root +`package.json` and merging: the `Release` workflow (`purview-release.yml`, +`release-mode: GitHubRelease`) runs the pipeline, tags `v{version}`, and uploads +the built `dist/` zip as a GitHub release asset. `deploy.yml` continues to +publish the site to GitHub Pages. + ## GitHub Pages deployment This repository is the organisation Pages repository diff --git a/justfile b/justfile index 6d42536..7943429 100644 --- a/justfile +++ b/justfile @@ -64,6 +64,10 @@ build: bun run data:sync bun run build +# Full CI validation chain used by the shared build pipeline (data sync → typecheck → build → checks). +ci-build: + bun run ci:build + # Preview the production build locally. preview: bun run preview diff --git a/package.json b/package.json index 042c55d..76a7801 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "name": "purview-dev", + "version": "0.1.0", "private": true, "description": "Purview-Dev public website and unified documentation portal (workspace root).", "license": "MIT", @@ -12,6 +13,7 @@ "check:assets": "bun run --cwd src check:assets", "check:generated": "bun run --cwd src check:generated", "check:links": "bun run --cwd src check:links", + "ci:build": "bun run data:sync && bun run typecheck && bun run check:assets && bun run build && bun run check:links && bun run check:generated && bun run test:dist", "clean": "bun run --cwd src clean", "data:sync": "bun run --cwd src data:sync", "dev": "bun run --cwd src dev", diff --git a/purview-build.json b/purview-build.json new file mode 100644 index 0000000..8945a31 --- /dev/null +++ b/purview-build.json @@ -0,0 +1,9 @@ +{ + "Build": { + "ProjectType": "Web", + "WebBuildCommand": "bun run ci:build" + }, + "Release": { + "Mode": "None" + } +} \ No newline at end of file diff --git a/src/src/components/SiteFooter.astro b/src/src/components/SiteFooter.astro index d6ccbec..7c0f907 100644 --- a/src/src/components/SiteFooter.astro +++ b/src/src/components/SiteFooter.astro @@ -2,7 +2,8 @@ import SiteBrand from '~/components/SiteBrand.astro'; import { NAV_ITEMS } from '~/components/SiteNav.astro'; import { loadProjects } from '~/lib/manifest/load'; -import { SITE } from '~/lib/site'; +import { siteVersion } from '~/lib/site-version'; +import { OWNER, SITE } from '~/lib/site'; import { withBase } from '~/lib/urls'; // Shuffled at build time so the footer doesn't always spotlight the same projects. @@ -10,6 +11,9 @@ const footerProjects = loadProjects() .filter((project) => project.status !== 'archived') .toSorted(() => Math.random() - 0.5) .slice(0, 3); + +const version = siteVersion(); +const releasesUrl = `${SITE.githubUrl}/${OWNER}.github.io/releases`; ---