CI/CD Pipelines
NMT uses GitHub Actions for continuous integration and deployment. There are three workflows.
Workflows
1. rust.yaml — Code Quality
Triggers: Pull requests and pushes to main/dev
| Step | Tool | Purpose |
|---|---|---|
| Format check | cargo fmt --check |
Enforces consistent code style |
| Compile check | cargo check |
Verifies the code compiles |
| Lint | cargo clippy |
Catches common Rust mistakes |
| Test | cargo test |
Runs the test suite |
This workflow runs on every PR and must pass before merging.
2. only_main.yaml — Build & Deploy
Triggers: Pushes to main, dev, or devops/* branches
| Step | Tool | Purpose |
|---|---|---|
| Build image | Buildah | Multi-stage container build |
| Security scan | Trivy | Scan for CRITICAL and HIGH CVEs |
| Push image | ghcr.io | Store image in GitHub Container Registry |
| Deploy | Helm | Deploy to DOKS cluster |
Important: The Trivy scan currently runs with exit-code: 0, meaning vulnerabilities are reported but don't block deployment. This is a known security consideration.
3. only_tag.yaml — Release
Triggers: Git tag pushes
Used for versioned releases. Follows a similar pattern to the main deployment workflow.
Pipeline Flow
Developer pushes to main
|
v
[Code Quality] cargo fmt + check + clippy + test
|
| (passes)
v
[Build] Buildah multi-stage image build
|
v
[Scan] Trivy vulnerability scan (non-blocking)
|
v
[Push] Image → ghcr.io tagged with Git SHA
|
v
[Deploy] Helm upgrade to DOKS stage namespace
|
v
Backend live at backend.stage.newmarkettrading.com
Secrets Used in CI/CD
The pipeline pulls secrets from GitHub Secrets to inject into the Helm deployment:
| Secret Category | Examples |
|---|---|
| Database | STAGE_DATABASE_URL, STAGE_REDIS_URL |
| RPC | RPC_ENDPOINTS, WS_ENDPOINTS |
| API Keys | KRYSTAL_API_KEY, GELATO_API_KEY, COINGECKO_API_KEY |
| Infrastructure | KUBE_CONFIG (base64-encoded DOKS access) |
Frontend CI/CD (frontend-app repo)
The frontend deploys to DO App Platform via GitHub Actions + doctl. No Dockerfile or Helm chart — DO builds and serves the Next.js app directly.
Production Deploy
Triggers: Push to main
| Step | What |
|---|---|
| Generate app spec | Inline YAML with services component (Node.js, port 3000) |
| Create or update app | doctl apps create/update with the spec |
| DO builds & deploys | DO pulls from GitHub, runs npm ci && npm run build, serves the app |
Preview Deploy
Triggers: Pull request opened/synchronized
| Step | What |
|---|---|
| Generate app spec | envsubst from .do/app-preview.template.yml with PR number |
| Create DO app | doctl apps create → nextjs-pr-N |
| Add DNS record | doctl compute domain records create → nextjs-pr-N.preview.newmarkettrading.com |
| Comment on PR | Posts the preview URL |
Preview Cleanup
Triggers: Pull request closed
Deletes the DO app and DNS record for the PR.
Docs CI/CD (docs repo)
The docs site deploys to DO App Platform as a static site. Same pattern as frontend but uses static_sites component.
Production Deploy
Triggers: Push to main
| Step | What |
|---|---|
| Generate app spec | Inline YAML with static_sites component, output dir _book |
| Create or update app | doctl apps create/update → nmt-docs |
| DO builds & deploys | DO pulls from GitHub, runs npm ci && npm run build, serves _book/ |
Preview Deploy / Cleanup
Same pattern as frontend — creates docs-pr-N.preview.newmarkettrading.com per PR, cleans up on close.