CI/CD Pipeline Operations
AcuOps runs a 3-tier CI/CD strategy across all services and customization projects.
Tier 1: Unit Tests
Fast, isolated tests that run on every push:
- Transform tests — Verify data mapping functions (e.g., Acumatica → HubSpot field transforms)
- Validation tests — Customization project XML validation (15+ rules)
- TypeScript compilation — Catches type errors before deploy
Tier 2: Integration Tests
API-based tests against live systems:
- Schema tests — Verify entity schemas, custom fields, and sub-entities via Acumatica REST API
- Sync property tests — Verify HubSpot custom properties exist with correct types
- Pipeline tests — Verify HubSpot pipeline stages match expected configuration
66 tests across 15 test files, running daily and after deploys.
Tier 3: End-to-End Tests
Full workflow validation:
- Customization deploy — Import → Publish → Schema verify
- Sync cycle — Acumatica fetch → HubSpot upsert → Write-back
- Health probes — All 12 infrastructure probes pass
GitHub Actions Configuration
Branch Protection
All repos use branch protection on main:
- Require PR reviews (1 approver)
- Require status checks to pass
- No force pushes
Secrets Management
danger
Never write secrets to GITHUB_OUTPUT — they lose masking and appear in plain text in logs. Pass secrets directly as env: vars on the step.
Common Workflow Pattern
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm test
Repository CI Status
| Repository | CI Type | Status |
|---|---|---|
| webhook-router | Build + studiob-qa gate | Active |
| business-dashboard | Build + type-check | Active |
| acumatica-ci-cd | Deploy pipeline | Active |
| ui-test-suite | 66 Playwright tests | Active |
| acumatica-mcp | Build + type-check | Active |
| devops-mcp | Build + type-check | Active |
| support-agent | Build + test | Active |
| provisioning-agent | Build + test | Active |
| integration-tester | Build + test | Active |
Health Check Pattern
All Railway services use a retry-based health check instead of sleep && curl:
- name: Wait for healthy
run: |
for i in $(seq 1 18); do
if curl -sf "$URL/health" > /dev/null 2>&1; then
echo "Healthy after $((i * 10))s"
exit 0
fi
sleep 10
done
echo "Failed after 180s"
exit 1