New Year Codebase Health Check: A January Checklist for Development Teams
A practical January checklist for development teams: audit dependencies, target test coverage, prune...
A payment API that fails a test suite at 2am is an incident. A release that reaches production with nobody able to say who approved it is a regulatory problem. UK fintech teams live with both, and GitHub Actions can carry more of that weight than most people assume — provided you build the pipeline with the paperwork in mind from the start, rather than the week before an audit.
Before writing a line of YAML, get three questions answered and written down somewhere in the repository. Everything else follows from them.
The answers depend on your regulatory position. FCA and PRA expectations around operational resilience, change management and segregation of duties apply broadly, and frameworks such as PCI DSS, ISO 27001 or SOC 2 add their own specifics. Your compliance lead — and, where relevant, your legal advisers — should confirm what applies to you. Your job is to make the pipeline the place where those controls actually live, so nobody has to reconstruct them from memory during a review.
Three workflow files will cover most fintech teams.
Put the shared parts into reusable workflows using workflow_call, so five repositories do not drift into five different definitions of "tested". A new service then inherits the same gate as an old one, which is a far easier argument to make to an auditor than a spreadsheet comparing job names.
Branch protection with required status checks is the backbone of the whole thing, and it has one common trap. If a job is skipped because of a path filter, the check can sit in an Expected state and block merges for the wrong reason. Run a final aggregator job with if: always() that depends on the real jobs and fails when any of them failed or was cancelled. Require that aggregator, not the individual jobs.
Then make the tests worth blocking on. Unit tests are the floor. Integration tests against a throwaway Postgres service container catch the migration mistakes that hurt most, and contract tests stop a change in one service quietly breaking another. Set a coverage threshold, but treat it as a ratchet rather than a target — raising it slowly beats arguing about it weekly. Flaky tests deserve their own rule: quarantine the test, open a ticket with an owner, fix it within the sprint. Unfixed flakiness is how teams learn to click "re-run" instead of reading the failure.
Layer the scans, and give each one a clear failure policy.
Fail the build on high and critical findings that are reachable in your code. Medium findings should become tickets with an owner and a date, not build failures. A pipeline that blocks on everything gets bypassed within a fortnight, and a bypassed control is worse than no control, because it looks like one.
Static cloud credentials stored as repository secrets are the habit worth breaking first. Use OpenID Connect to let the workflow assume a cloud role for the duration of the job. Nothing long-lived to leak, rotate or explain.
For production, use an environment with required reviewers and restrict the list of approvers to people whose role justifies it. GitHub records who approved each deployment and when — that approval entry is often the single most useful piece of evidence you will produce. Keep secrets in environment scope rather than repository scope, mask anything that might be echoed, and keep a written rotation schedule for whatever genuinely cannot be short-lived.
Stream the organisation audit log to your SIEM — S3, Splunk, Event Hubs and similar destinations are all supported. Merges, approval decisions, permission changes and workflow edits then land in the same place as the rest of your security telemetry, with retention you control.
In the repository, enable required reviews via CODEOWNERS, consider signed commits, and prevent force pushes to protected branches. Artifacts expire by default after a set retention period, so raise it deliberately and copy release evidence — test reports, scan results, the SBOM — into storage you own, ideally with object lock enabled. Tie each run back to a change record: a ticket reference in the branch name or pull request description gives you the "why" to sit alongside the pipeline's "how".
Once the pipeline works, resist the urge to add fifteen more jobs. Record why each gate exists in a short decision note next to the workflow, review the thresholds quarterly, and rehearse the emergency path so a genuine incident does not become the first time anyone tries to bypass an approval step. If a control is unclear, or the answer depends on how your firm is authorised, ask your compliance team or legal advisers rather than guessing. The goal is a pipeline nobody thinks about, quietly producing the evidence you would otherwise spend a fortnight assembling.
Photo: Mikhail Nilov / Pexels
A practical January checklist for development teams: audit dependencies, target test coverage, prune...
CSS Grid usually breaks on mobile because of sizing floors, not the grid itself. Here's why implicit...
A practical checklist for keeping personal data out of application logs, setting sensible retention...