Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
version: 2

updates:
- package-ecosystem: npm
directory: /website
schedule:
interval: weekly
target-branch: main
open-pull-requests-limit: 3
cooldown:
default-days: 7
semver-major-days: 30
semver-minor-days: 7
semver-patch-days: 3
groups:
development-dependencies:
dependency-type: development
update-types:
- minor
- patch

- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
target-branch: main
open-pull-requests-limit: 1
groups:
github-actions:
patterns:
- "*"
151 changes: 151 additions & 0 deletions .github/workflows/pages-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
name: Pages deployment

on:
workflow_run:
workflows:
- Website checks
types:
- completed
workflow_dispatch:
inputs:
run_id:
description: Successful Website checks run containing inkcre-website-dist
required: true
type: number

permissions:
actions: read
contents: read

concurrency:
group: pages-main
cancel-in-progress: true

jobs:
identity:
name: Resolve trusted production identity
if: >-
github.event_name == 'workflow_dispatch' || (
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.head_branch == 'main'
)
runs-on: ubuntu-latest
outputs:
head_sha: ${{ steps.identity.outputs.head_sha }}
run_id: ${{ steps.identity.outputs.run_id }}
steps:
- name: Resolve the exact current main artifact
id: identity
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const runId = context.eventName === 'workflow_dispatch'
? Number(context.payload.inputs.run_id)
: context.payload.workflow_run.id
const { data: run } = await github.rest.actions.getWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: runId,
})
if (run.name !== 'Website checks' || run.path !== '.github/workflows/website-check.yml') {
core.setFailed('Artifact must come from the trusted Website checks workflow.')
return
}
if (run.conclusion !== 'success' || run.head_branch !== 'main') {
core.setFailed('Production delivery requires a successful main run.')
return
}
const currentMain = await github.rest.git.getRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: 'heads/main',
})
if (currentMain.data.object.sha !== run.head_sha) {
core.setFailed('Production delivery requires the current exact main head.')
return
}
core.setOutput('head_sha', run.head_sha)
core.setOutput('run_id', String(runId))

deploy:
name: Deploy checked website artifact
needs: identity
permissions:
actions: read
contents: read
deployments: write
runs-on: ubuntu-latest
timeout-minutes: 20
environment:
name: production
url: https://inkcre.dev
steps:
- name: Checkout the trusted delivery controller
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: main
path: controller
persist-credentials: false

- name: Set up Node
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
with:
node-version-file: controller/website/package.json

- name: Download the exact checked artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: inkcre-website-dist
path: .pages-delivery/dist
run-id: ${{ needs.identity.outputs.run_id }}
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Reverify main before delivery
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
RELEASE_HEAD_SHA: ${{ needs.identity.outputs.head_sha }}
with:
script: |
const currentMain = await github.rest.git.getRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: 'heads/main',
})
if (currentMain.data.object.sha !== process.env.RELEASE_HEAD_SHA) {
core.setFailed('Main changed after artifact selection; refusing delivery.')
}

- name: Ensure the Pages project
run: node controller/website/scripts/configure-pages.mjs project
env:
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_PAGES_DOMAIN: inkcre.dev
CLOUDFLARE_PAGES_PROJECT: ${{ vars.CLOUDFLARE_PAGES_PROJECT }}

- name: Deploy to Cloudflare Pages
id: pages
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
packageManager: npm
wranglerVersion: 4.114.0
workingDirectory: .pages-delivery
command: >-
pages deploy dist --project-name=${{ vars.CLOUDFLARE_PAGES_PROJECT }} --branch=main

- name: Ensure the custom domain
run: node controller/website/scripts/configure-pages.mjs domain
env:
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_PAGES_DOMAIN: inkcre.dev
CLOUDFLARE_PAGES_PROJECT: ${{ vars.CLOUDFLARE_PAGES_PROJECT }}

- name: Smoke-test Pages and inkcre.dev
run: node controller/website/scripts/verify-pages-deployment.mjs
env:
CLOUDFLARE_PAGES_DEPLOYMENT_ID: ${{ steps.pages.outputs.pages-deployment-id }}
CLOUDFLARE_PAGES_DEPLOYMENT_URL: ${{ steps.pages.outputs.deployment-url }}
INKCRE_WEBSITE_ORIGIN: https://inkcre.dev
53 changes: 53 additions & 0 deletions .github/workflows/website-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Website checks

on:
pull_request:
branches:
- main
push:
branches:
- main
workflow_dispatch:

permissions:
contents: read

concurrency:
group: website-checks-${{ github.ref }}
cancel-in-progress: true

jobs:
website:
name: Website contract
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Install the pinned pnpm release
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
with:
package_json_file: website/package.json

- name: Set up Node
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
with:
node-version-file: website/package.json
cache: pnpm
cache-dependency-path: website/pnpm-lock.yaml

- name: Install the frozen website package
run: pnpm --dir website install --frozen-lockfile

- name: Verify the website contract
run: pnpm --dir website check

- name: Upload the exact checked website artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: inkcre-website-dist
path: website/.vitepress/dist
if-no-files-found: error
include-hidden-files: true
retention-days: 7
Loading