GitHub β NHS Quickstart
Centralise code, reviews, and CI/CD. Keep work private inside your Trust org, open-source whatβs reusable, and use Actions with Environments and approvals to deploy safely.
Great for: Everyone (BI Analyst Β· Data Scientist Β· Developer Β· Data Engineer Β· IG).
βοΈ 10-minute setupβ
- Create or join your Trustβs GitHub Organization.
- Create a private repo for Trust work (or public if no sensitive context).
- Push your local project:
git remote add origin https://github.com/<org>/<repo>.git
git push -u origin main
Add collaborators via Teams (least privilege).
π βHello NHSβ CI (Actions)β
Create .github/workflows/ci.yml:
name: CI
on:
push:
branches: [ main ]
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Smoke test
run: echo "OK"
Open a Pull Request β see checks run automatically.
π§± Useful workflows by stackβ
- A) Python (lint + tests)
- B) Node/React (build)
- C) R (render RMarkdown)
For pandas/ETL/Dash/FastAPI projects.
name: Python
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: '3.11' }
- run: pip install -r requirements.txt || true
- run: pip install pytest
- run: pytest -q || echo "No tests yet"
For React/Next.js front-ends.
name: Node
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- run: npm run build
For R/Shiny/RMarkdown tasks.
name: R
on: [push, pull_request]
jobs:
rmd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: r-lib/actions/setup-r@v2
- run: Rscript -e 'if (file.exists("report.Rmd")) quarto::quarto_render("report.Rmd") else cat("No Rmd")'
π Secrets & Environmentsβ
Store credentials in Repository β Settings β Secrets and variables β Actions. For safer releases, use Environments with required reviewers and deployment branches.
- AWS OIDC (no long-lived keys)
- Azure OIDC (Entra ID)
Federate Actions to AWS with short-lived credentials.
name: Deploy API (AWS)
on: workflow_dispatch
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::<account-id>:role/github-deploy
aws-region: eu-west-2
- run: echo "Deploy with AWS CLI here"
environment: prod
Login without saving secrets using Entra ID federation.
name: Deploy Web (Azure)
on: workflow_dispatch
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
enable-AzPSSession: false
- run: echo "Deploy with az CLI here"
environment: prod
π§© Repo hygiene & templatesβ
- Branch protection: require PR reviews + passing checks on
main. - CODEOWNERS: auto-request reviewers for specific folders.
# BI SQL must be reviewed by the BI team
/sql/ @nhs-org/bi-team
- Issue & PR templates: ask IG questions up front.
### Data sources
### PHI/PII handling
### Suppression rules
### DPIA reference
- Security policy: add
SECURITY.mdwith contact and disclosure steps. - Dependabot: keep dependencies patched (Actions + npm + pip).
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule: { interval: "weekly" }
- package-ecosystem: "npm"
directory: "/"
schedule: { interval: "weekly" }
- package-ecosystem: "pip"
directory: "/"
schedule: { interval: "weekly" }
π¦ Packages & Pagesβ
- GHCR (GitHub Container Registry) for Docker images.
name: Publish image
on: push
jobs:
docker:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
push: true
tags: ghcr.io/${{ github.repository }}:latest
- GitHub Pages for static sites (Evidence.dev, docs). Enable in Settings β Pages, then:
name: Pages
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build && touch dist/.nojekyll
- uses: actions/upload-pages-artifact@v3
with: { path: "dist" }
deploy:
needs: build
permissions: { pages: write, id-token: write }
runs-on: ubuntu-latest
steps:
- uses: actions/deploy-pages@v4
π IG & safety checklistβ
- Keep repos private unless the content is truly public.
- Never commit secrets; use Secrets/Environments and OIDC where possible.
- Document data sources, suppression rules, and retention.
- Require PR reviews; CODEOWNERS for sensitive folders.
- Enable Dependabot and limit runner permissions to least privilege.
π Measuring impactβ
- Review coverage: % merges via PR with at least 1 reviewer.
- Security: zero leaked secrets; Dependabot PRs merged.
- Delivery: build success rate; median PR lead time.
- Reproducibility: clean clone β successful build in CI.
π See alsoβ
Whatβs next?
Youβve completed the Learn β GitHub stage. Keep momentum: