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
3 changes: 0 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,3 @@ ZENDESK_KEY=<zendesk key>
GTM_ID=<google tag manager id>

BRANCH=optional (sets the edit path)

FEATURE_DEV_FLAG=false
FEATURE_NEW_PRODUCTS_FLAG=false
13 changes: 11 additions & 2 deletions .github/workflows/check-formatting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,19 @@ jobs:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci
# The repo .npmrc is credential-less; inject feed creds into ~/.npmrc
- name: Authenticate to codat-npm feed
run: |
{
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:username=codat"
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:_password=${NPM_TOKEN}"
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:email=npm-requires-email@example.com"
} >> ~/.npmrc
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Install dependencies
run: npm ci

- name: Check formatting
run: npm run format:js:check
13 changes: 11 additions & 2 deletions .github/workflows/check-markdown-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,19 @@ jobs:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci
# The repo .npmrc is credential-less; inject feed creds into ~/.npmrc
- name: Authenticate to codat-npm feed
run: |
{
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:username=codat"
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:_password=${NPM_TOKEN}"
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:email=npm-requires-email@example.com"
} >> ~/.npmrc
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Install dependencies
run: npm ci

- name: Check markdown formatting with Prettier
run: npm run format:mdx:check
13 changes: 11 additions & 2 deletions .github/workflows/check-spelling.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,19 @@ jobs:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm install -g cspell
# The repo .npmrc is credential-less; inject feed creds into ~/.npmrc
- name: Authenticate to codat-npm feed
run: |
{
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:username=codat"
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:_password=${NPM_TOKEN}"
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:email=npm-requires-email@example.com"
} >> ~/.npmrc
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Install dependencies
run: npm install -g cspell

- name: Run spell check
run: cspell "**/*.md" "**/*.mdx" --config cspell.json
16 changes: 12 additions & 4 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,27 @@ jobs:
node-version: 24
cache: npm

- name: Install dependencies
run: npm ci
# The repo .npmrc is credential-less (the K8s image build authenticates
# via ADO npmAuthenticate); GH-hosted builds inject creds here instead.
- name: Authenticate to codat-npm feed
run: |
{
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:username=codat"
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:_password=${NPM_TOKEN}"
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:email=npm-requires-email@example.com"
} >> ~/.npmrc
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Install dependencies
run: npm ci

- name: Build site
run: npm run build
env:
ZENDESK_KEY: ${{ secrets.ZENDESK_KEY }}
AMPLITUDE_API_KEY: ${{ secrets.AMPLITUDE_API_KEY }}
GTM_ID: ${{ vars.GTM_ID }}
FEATURE_DEV_FLAG: ${{ vars.FEATURE_DEV_FLAG }}
FEATURE_NEW_PRODUCTS_FLAG: ${{ vars.FEATURE_NEW_PRODUCTS_FLAG }}

- uses: actions/configure-pages@v6

Expand Down
19 changes: 13 additions & 6 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,27 @@ jobs:
node-version: 24
cache: npm

# The ADO registry in .npmrc requires auth even to install, so PR
# builds need NPM_TOKEN too (fork PRs don't get secrets and will fail)
- name: Install dependencies
run: npm ci
# The ADO registry requires auth even to install; the repo .npmrc is
# credential-less so creds go into ~/.npmrc here (fork PRs don't get
# secrets and will fail)
- name: Authenticate to codat-npm feed
run: |
{
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:username=codat"
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:_password=${NPM_TOKEN}"
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:email=npm-requires-email@example.com"
} >> ~/.npmrc
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Install dependencies
run: npm ci

- name: Build site
run: npm run build
env:
# plugin-google-gtag requires a trackingID, so PR builds need it too
GTM_ID: ${{ vars.GTM_ID }}
FEATURE_DEV_FLAG: ${{ vars.FEATURE_DEV_FLAG }}
FEATURE_NEW_PRODUCTS_FLAG: ${{ vars.FEATURE_NEW_PRODUCTS_FLAG }}

# Link checking reuses the build above: linkinator serves ./build on an
# ephemeral localhost port, so no deployed preview environment is needed.
Expand Down
4 changes: 0 additions & 4 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
registry=https://pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/
always-auth=true
save-exact=true
//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:username=codat
//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:_password=${NPM_TOKEN}
//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:email=engineering@codat.io
10 changes: 10 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM nginx:1.29.6-alpine-slim AS final

COPY --from=build /src/build /usr/share/nginx/html
COPY --from=build /src/nginx.conf /etc/nginx/nginx.conf

RUN rm /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
83 changes: 83 additions & 0 deletions deployment/build.azure-pipelines.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: $(Date:yyyy.M.dd).$(Rev:r)

trigger:
branches:
include:
- 'main'
paths:
exclude: []

pr:
branches:
include:
- 'main'

resources:
repositories:
- repository: 'templates'
type: 'git'
name: 'Codat/YAMLBuildTemplates'

# Array values as Variables not supported by ADO
parameters:
- name: ImagesToPublish
type: object
default:
- 'codat.docs.ui'

- name: DeploymentEnvironments
type: object
default:
- name: integration
shortCode: intg
pool:
name: codat-intg-managed-devops-pool-linux
demands:
- CustomCapabilities -equals $(Build.Repository.Name)
registryName: codatintgregistry

- name: production
shortCode: prod
pool: codat-prod-managed-devops-pool-linux
registryName: codatprodregistry

stages:
- stage: 'build'
pool:
name: 'codat-intg-managed-devops-pool-linux'
demands:
- CustomCapabilities -equals $(Build.Repository.Name)
jobs:
- template: Helm/build.frontend.job.yaml@templates
parameters:
ImagesToPublish: ${{ parameters.ImagesToPublish }}
Version: '$(Build.BuildNumber)'
BuildFolder: deployment
# Images are Git LFS-tracked; a plain checkout leaves 130-byte
# pointer files and Docusaurus only WARNS on unreadable images,
# so the build would stay green while shipping broken images.
GitLfs: true
# Build-time site config, fetched on the agent (the vault blocks
# public network access, so a KV-linked variable group can't read
# it — only the pool agents can, via the private endpoint). KV
# secret names can't contain underscores, hence the hyphenated
# $() references; the bake file maps them to the underscored args.
KeyVaultName: codat-integration
KeyVaultSecretsFilter: 'docs-zendesk-key,docs-amplitude-api-key,docs-gtm-id'
AdditionalBakeEnvironment:
ZENDESK_KEY: $(docs-zendesk-key)
AMPLITUDE_API_KEY: $(docs-amplitude-api-key)
GTM_ID: $(docs-gtm-id)

- ${{ if not(in( variables['Build.Reason'], 'PullRequest' )) }}:
- ${{ each env in parameters.DeploymentEnvironments }}:
- ${{ if or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), ne(env.name, 'production')) }}:
- stage: ${{ env.name }}
pool: ${{ env.pool }}
jobs:
- template: Helm/deploy.job.yaml@templates
parameters:
Environment: ${{ env.name }}
RegistryName: ${{ env.registryName }}
ImagesToPublish: ${{ parameters.ImagesToPublish }}
ArgoApplicationName: docs
8 changes: 8 additions & 0 deletions deployment/charts/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: 'v2'
name: 'codat.docs'
type: 'application'
version: '0.0.1' # this is overwritten by the pipeline
dependencies:
- name: 'codat-classic-app'
version: '>=2.6.1'
repository: 'oci://codatintgregistry.azurecr.io/base-charts'
19 changes: 19 additions & 0 deletions deployment/charts/values-intg.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
codat-classic-app:
components:
- name: ui
image: codatintgregistry.azurecr.io/codat.docs.ui
routing:
- hosts: ["docs-integration.codat.io"]
containerPort: 80
statusPath: "/"
horizontalPodAutoscaling:
minReplicas: 1
maxReplicas: 2
podDisruptionBudget:
minAvailable: 0
resources:
requests:
memory: 20Mi
cpu: 10m
limits:
memory: 100Mi
21 changes: 21 additions & 0 deletions deployment/charts/values-prod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
codat-classic-app:
components:
- name: ui
image: codatprodregistry.azurecr.io/codat.docs.ui
routing:
- hosts: ["docs.codat.io"]
containerPort: 80
statusPath: "/"
# High-traffic, client-facing (unlike legal): sized up per EXP-2106.
# Review requests/limits against real usage after a week in prod.
horizontalPodAutoscaling:
minReplicas: 2
maxReplicas: 4
podDisruptionBudget:
minAvailable: 1
resources:
requests:
memory: 50Mi
cpu: 25m
limits:
memory: 200Mi
7 changes: 7 additions & 0 deletions deployment/charts/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
codat-classic-app:
appVersion: 0.0.0
metadata:
serviceName: docs
owningTeam: &team Pepper
env:
Codat_This_OwningTeam: *team
32 changes: 32 additions & 0 deletions deployment/docker/build.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
ARG DOCKER_REGISTRY

FROM ${DOCKER_REGISTRY:-}base-images/node-build:24-bookworm-slim AS build

WORKDIR /src

COPY package.json .
COPY package-lock.json .
# Credential-less in the repo; the ADO pipeline's npm authenticate step injects
# feed credentials into it before the bake (same mechanism as legal / admin-ui).
# Local builds need your own authenticated .npmrc.
COPY .npmrc .

RUN npm ci

# .git IS dockerignored: this site doesn't use showLastUpdateAuthor/Time, so
# the build never shells out to git (unlike legal).
COPY . .

ENV CI=true

# Build-time site config, baked into the static output (docusaurus.config.js
# customFields). Values arrive via docker-bake.hcl from the pipeline env;
# BRANCH is deliberately unset — editUrl falls back to main.
ARG ZENDESK_KEY
ARG AMPLITUDE_API_KEY
ARG GTM_ID
ENV ZENDESK_KEY=${ZENDESK_KEY} \
AMPLITUDE_API_KEY=${AMPLITUDE_API_KEY} \
GTM_ID=${GTM_ID}

RUN npm run build
14 changes: 14 additions & 0 deletions deployment/docker/build.dockerfile.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# .git is excluded: no showLastUpdateAuthor/Time in docusaurus.config.js, so
# the build never reads git history (legal keeps it; we don't need it).
.git
.vscode
.dockerignore
.gitignore
.env
build
node_modules
Dockerfile
README.md
deployment
.github
code_utils
46 changes: 46 additions & 0 deletions deployment/docker/docker-bake.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
variable VERSION {
default = "dev"
}

variable DOCKER_REGISTRY {
default = "codatintgregistry.azurecr.io/"
}

# Build-time site config; bake reads these from the pipeline step's env
# (values come from the codat-docs-build variable group).
variable ZENDESK_KEY {
default = ""
}

variable AMPLITUDE_API_KEY {
default = ""
}

variable GTM_ID {
default = ""
}

group "default" {
targets = [
"build",
"app"
]
}

target "build" {
context = "./"
dockerfile = "deployment/docker/build.dockerfile"
args = {
DOCKER_REGISTRY = "${DOCKER_REGISTRY}"
ZENDESK_KEY = "${ZENDESK_KEY}"
AMPLITUDE_API_KEY = "${AMPLITUDE_API_KEY}"
GTM_ID = "${GTM_ID}"
}
tags = [ "codat.docs.build:${VERSION}" ]
}

target "app" {
contexts = { "build" = "target:build" }
dockerfile = "Dockerfile"
tags = [ "codat.docs.ui:${VERSION}" ]
}
Loading
Loading