Fail Fast
Run validation first before other checks. Invalid docs should fail immediately.
This guide covers integrating Cortex TMS into your continuous integration and continuous deployment pipelines. You’ll learn how to automate documentation validation, enforce patterns in code reviews, archive sprints automatically, release with validated docs, and deploy with confidence.
Without CI/CD integration, documentation validation and pattern enforcement rely on developers remembering to run commands manually. This leads to:
CI/CD integration fixes this by making validation mandatory before merging, releasing, or deploying.
GitHub Actions is the easiest platform to integrate with Cortex TMS.
Create .github/workflows/validate.yml:
name: Validate Cortex TMS
on: push: branches: [main, develop] pull_request:
jobs: validate: runs-on: ubuntu-latest
steps: - name: Checkout code uses: actions/checkout@v4
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20'
- name: Install dependencies run: npm ci
- name: Install cortex-tms
- name: Validate Cortex TMS run: cortex-tms validate --strict
- name: Run linting run: npm run lint
- name: Run type checking run: npm run type-check
- name: Run tests run: npm test -- --coverage
- name: Upload coverage uses: codecov/codecov-action@v3 with: files: ./coverage/coverage-final.json fail_ci_if_error: trueWhat this does:
Create .github/workflows/pr-checks.yml:
name: PR Checks
on: pull_request: types: [opened, synchronize, reopened]
jobs: pattern-check: runs-on: ubuntu-latest
steps: - name: Checkout code uses: actions/checkout@v4
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20'
- name: Install dependencies run: npm ci
- name: Install cortex-tms
- name: Check if PATTERNS.md was updated run: | if git diff origin/main...HEAD --name-only | grep -q "docs/core/PATTERNS.md"; then echo "✓ PATTERNS.md was updated" else echo "⚠️ New code patterns detected but PATTERNS.md not updated" echo "Consider updating docs/core/PATTERNS.md with your new pattern" fi
- name: Check if NEXT-TASKS.md marks task complete run: | # Verify task completion if implementing a feature if git diff origin/main...HEAD --name-only | grep -q "src/"; then echo "✓ Code changes detected" echo "Please verify NEXT-TASKS.md marks related tasks as complete" fi
- name: Validate documentation run: cortex-tms validate --strictWhat this does:
Create .github/workflows/archive-sprint.yml:
name: Archive Completed Sprint
on: schedule: # Every Friday at 5 PM UTC - cron: '0 17 * * 5' workflow_dispatch:
jobs: archive: runs-on: ubuntu-latest
steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20'
- name: Install dependencies run: npm ci
- name: Install cortex-tms
- name: Check if sprint is complete id: sprint-complete run: | # Count incomplete tasks incomplete=$(grep -c "^- \[ \]" NEXT-TASKS.md || echo 0)
if [ "$incomplete" -eq 0 ]; then echo "sprint_complete=true" >> $GITHUB_OUTPUT else echo "sprint_complete=false" >> $GITHUB_OUTPUT echo "⚠️ Sprint has $incomplete incomplete tasks. Skipping archive." fi
- name: Create archive file if: steps.sprint-complete.outputs.sprint_complete == 'true' run: | date_str=$(date +%Y-%m-%d) sprint_name=$(grep "## Active Sprint:" NEXT-TASKS.md | head -1 | sed 's/## Active Sprint: //' | sed 's/ (.*//') archive_file="docs/archive/sprint-${date_str}-${sprint_name// /-}.md"
# Create archive with completed tasks cp NEXT-TASKS.md "$archive_file" echo "✓ Created $archive_file"
- name: Clear completed tasks from NEXT-TASKS.md if: steps.sprint-complete.outputs.sprint_complete == 'true' run: | # Keep only the header and active sprint section head -n 5 NEXT-TASKS.md > NEXT-TASKS.tmp mv NEXT-TASKS.tmp NEXT-TASKS.md
- name: Commit and push if: steps.sprint-complete.outputs.sprint_complete == 'true' run: | git config user.name "cortex-tms[bot]" git config user.email "[email protected]" git add docs/archive/ NEXT-TASKS.md git commit -m "docs: archive completed sprint
Co-Authored-By: Cortex TMS ([email protected])" git push origin mainWhat this does:
Create .github/workflows/release.yml:
name: Release
on: push: tags: - 'v*'
jobs: validate-and-release: runs-on: ubuntu-latest
steps: - name: Checkout code uses: actions/checkout@v4
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20'
- name: Install dependencies run: npm ci
- name: Install cortex-tms
- name: Validate documentation run: cortex-tms validate --strict
- name: Check CHANGELOG updated run: | # Extract version from tag version=${GITHUB_REF#refs/tags/v}
# Check if CHANGELOG mentions this version if grep -q "## \[$version\]" CHANGELOG.md; then echo "✓ CHANGELOG updated for version $version" else echo "✗ CHANGELOG.md must be updated with version $version" exit 1 fi
- name: Run full test suite run: npm test
- name: Build run: npm run build
- name: Create GitHub Release uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ github.ref }} release_name: Release ${{ github.ref }} body: | See CHANGELOG.md for details. draft: false prerelease: falseWhat this does:
Add this to your README.md:
[](https://github.com/your-org/your-repo/actions/workflows/validate.yml)[](https://github.com/your-org/your-repo/actions/workflows/test.yml)[](https://codecov.io/gh/your-org/your-repo)This shows project health at a glance.
If you use GitLab, integrate Cortex TMS with .gitlab-ci.yml.
Create .gitlab-ci.yml:
image: node:20
stages: - validate - test - build - release
variables: npm_config_cache: "$CI_PROJECT_DIR/.npm"
cache: paths: - .npm/ - node_modules/
before_script: - npm ci
validate:cortex-tms: stage: validate script: - cortex-tms validate --strict only: - merge_requests - main - develop allow_failure: false
validate:lint: stage: validate script: - npm run lint only: - merge_requests - main - develop
validate:type-check: stage: validate script: - npm run type-check only: - merge_requests - main - develop
test:unit: stage: test script: - npm test -- --coverage coverage: '/Lines\s*:\s*(\d+\.\d+)%/' artifacts: reports: coverage_report: coverage_format: cobertura path: coverage/cobertura-coverage.xml paths: - coverage/ expire_in: 30 days only: - merge_requests - main - develop
build:production: stage: build script: - npm run build artifacts: paths: - dist/ expire_in: 1 day only: - tags - main
release:create: stage: release script: - npm install -g semantic-release @semantic-release/git @semantic-release/gitlab - semantic-release only: - main when: manualWhat this does:
Create .gitlab/merge_request_templates/default.md:
## Description
<!-- What does this MR do? -->
## Type of Change
- [ ] Feature- [ ] Bug fix- [ ] Documentation- [ ] Refactor- [ ] Test improvement
## Checklist
### Code Quality- [ ] Code follows patterns in `docs/core/PATTERNS.md`- [ ] Tests added/updated- [ ] All tests pass locally- [ ] Linting passes locally
### Documentation- [ ] `cortex-tms validate` passes- [ ] Updated PATTERNS.md if adding new patterns- [ ] Created ADR if making architectural decision- [ ] Updated NEXT-TASKS.md if completing tasks
### Testing- [ ] Unit tests added- [ ] Integration tests added (if applicable)- [ ] Coverage maintained or improved
## Related Issues
<!-- Link to GitLab issues: Closes #123 -->If you use CircleCI, here’s how to integrate Cortex TMS.
Create .circleci/config.yml:
version: 2.1
orbs: node: circleci/node@5 codecov: codecov/codecov@3
jobs: validate: executor: node/default steps: - checkout - node/install-packages - run: name: Install cortex-tms - run: name: Validate Cortex TMS command: cortex-tms validate --strict - run: name: Run linting command: npm run lint - run: name: Run type checking command: npm run type-check
test: executor: node/default steps: - checkout - node/install-packages - run: name: Run tests with coverage command: npm test -- --coverage - codecov/upload: file: ./coverage/coverage-final.json
build: executor: node/default steps: - checkout - node/install-packages - run: name: Build production command: npm run build - persist_to_workspace: root: . paths: - dist/
release: executor: node/default steps: - checkout - attach_workspace: at: . - node/install-packages - run: name: Install cortex-tms - run: name: Validate before release command: cortex-tms validate --strict - run: name: Verify CHANGELOG command: | version=${CIRCLE_TAG#v} if grep -q "## \[$version\]" CHANGELOG.md; then echo "✓ CHANGELOG updated" else echo "✗ CHANGELOG not updated for $version" exit 1 fi - run: name: Setup npm auth command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc - run: name: Publish to npm command: npm publish
workflows: validate-and-test: jobs: - validate: filters: branches: only: - main - develop - /^feature\/.*/ - test: filters: branches: only: - main - develop - /^feature\/.*/ - build: requires: - validate - test
release: jobs: - validate: filters: tags: only: /^v.*/ branches: ignore: /.*/ - test: filters: tags: only: /^v.*/ branches: ignore: /.*/ - build: requires: - validate - test filters: tags: only: /^v.*/ branches: ignore: /.*/ - release: requires: - build filters: tags: only: /^v.*/ branches: ignore: /.*/What this does:
Use pre-commit hooks to validate locally before pushing.
npm install -D husky lint-staged
npx husky installnpx husky add .husky/pre-commit "cortex-tms validate && npm run lint"npx husky add .husky/pre-push "npm test"Update package.json:
{ "lint-staged": { "*.ts": [ "eslint --fix", "prettier --write" ], "*.md": [ "prettier --write" ], "NEXT-TASKS.md": [ "cortex-tms validate" ], "PATTERNS.md": [ "cortex-tms validate" ] }}Integrate Cortex TMS validation into your deployment process.
Add this to your deployment script (deploy.sh):
#!/bin/bashset -e
echo "🔍 Validating Cortex TMS..."cortex-tms validate --strict
echo "🧪 Running tests..."npm test
echo "🏗️ Building..."npm run build
echo "📦 Deploying to production..."# Your deployment command here# Example: vercel --prod
echo "✅ Deployment complete!"Create .github/workflows/pre-deploy-check.yml:
name: Pre-Deploy Checks
on: workflow_dispatch: inputs: environment: description: 'Deployment environment' required: true default: 'staging' type: choice options: - staging - production
jobs: pre-deploy-checks: runs-on: ubuntu-latest
steps: - name: Checkout code uses: actions/checkout@v4
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20'
- name: Install dependencies run: npm ci
- name: Install cortex-tms
- name: Validate documentation run: cortex-tms validate --strict
- name: Run full test suite run: npm test -- --coverage
- name: Build run: npm run build
- name: Check if git is clean run: | if [ -z "$(git status --porcelain)" ]; then echo "✓ Git working directory is clean" else echo "✗ Git working directory has uncommitted changes" git status exit 1 fi
- name: Check if on main branch if: github.event.inputs.environment == 'production' run: | if [ "$(git rev-parse --abbrev-ref HEAD)" == "main" ]; then echo "✓ On main branch" else echo "✗ Production deployments require main branch" exit 1 fi
- name: Ready for deployment run: | echo "✅ All pre-deploy checks passed!" echo "Environment: ${{ github.event.inputs.environment }}" echo "Ready to deploy"What this does:
Create a script to track validation health (scripts/track-validation.js):
const fs = require('fs');const path = require('path');const { execSync } = require('child_process');
const validationLog = { timestamp: new Date().toISOString(), branch: process.env.GITHUB_REF || 'local', commit: process.env.GITHUB_SHA || 'local', checks: {},};
try { // Check CLAUDE.md const claudeMd = fs.readFileSync('CLAUDE.md', 'utf8'); validationLog.checks.claudeMd = { exists: true, size: claudeMd.length, sections: (claudeMd.match(/^## /gm) || []).length, };} catch { validationLog.checks.claudeMd = { exists: false };}
try { // Check PATTERNS.md const patternsMd = fs.readFileSync('docs/core/PATTERNS.md', 'utf8'); validationLog.checks.patternsMd = { exists: true, size: patternsMd.length, patterns: (patternsMd.match(/^## /gm) || []).length, };} catch { validationLog.checks.patternsMd = { exists: false };}
try { // Check task completion rate const nextTasks = fs.readFileSync('NEXT-TASKS.md', 'utf8'); const totalTasks = (nextTasks.match(/^- \[./gm) || []).length; const completedTasks = (nextTasks.match(/^- \[x\]/gm) || []).length;
validationLog.checks.taskCompletion = { total: totalTasks, completed: completedTasks, percentage: totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0, };} catch { validationLog.checks.taskCompletion = { error: 'Could not parse NEXT-TASKS.md' };}
// Log resultsconsole.log(JSON.stringify(validationLog, null, 2));
// Save to file for historical trackingconst logsDir = '.validation-logs';if (!fs.existsSync(logsDir)) { fs.mkdirSync(logsDir);}
const logFile = path.join(logsDir, `${Date.now()}.json`);fs.writeFileSync(logFile, JSON.stringify(validationLog, null, 2));Create a workflow that sends Slack alerts:
name: Validation Alert
on: workflow_run: workflows: ["Validate Cortex TMS"] types: [completed]
jobs: notify: runs-on: ubuntu-latest if: ${{ github.event.workflow_run.conclusion == 'failure' }}
steps: - name: Send Slack notification with: payload: | { "text": "🚨 Cortex TMS Validation Failed", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "Cortex TMS validation failed on `${{ github.ref_name }}`\n*Commit:* <${{ github.event.workflow_run.html_url }}|${{ github.event.workflow_run.head_commit.message }}>" } }, { "type": "actions", "elements": [ { "type": "button", "text": { "type": "plain_text", "text": "View Workflow" }, "url": "${{ github.event.workflow_run.html_url }}" } ] } ] } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOKFail Fast
Run validation first before other checks. Invalid docs should fail immediately.
Require Tests with Changes
Every code change must include tests. CI should fail if coverage drops.
Validate Before Release
Never release without validating docs, updating CHANGELOG, and running full tests.
Archive Automatically
Use scheduled workflows to archive completed sprints. Keep NEXT-TASKS.md lean.
Use Status Badges
Display CI status in README. Green badges indicate healthy projects.
Monitor Metrics
Track validation health, test coverage, and pattern compliance over time.
Symptoms:
cortex-tms validate works on your machineSolutions:
Check file encoding
CI might use different line endings. Ensure Unix line endings:
dos2unix NEXT-TASKS.md PATTERNS.mdCheck file permissions
Some files might need executable permissions:
chmod +x deploy.shVerify Node version
CI might use different Node version:
node --version# Compare with: cat .nvmrc or .node-versionCheck environment variables
Missing env vars can cause validation failures:
# List all env vars in your workflow- name: Debug env vars run: env | grep -E "(NODE|NPM|CORTEX)" | sortSymptoms:
Solutions:
Check task completion
Archive only runs if ALL tasks are complete. Verify:
grep -c "^- \[ \]" NEXT-TASKS.md# Should output 0Check workflow logs
View Actions/Pipelines → Archive Sprint → Logs to see what failed.
Manually archive if needed
git checkout -b docs/archive-sprint
# Create archive filedate_str=$(date +%Y-%m-%d)cp NEXT-TASKS.md "docs/archive/sprint-${date_str}.md"
# Clear for next sprintecho "# Current Tasks" > NEXT-TASKS.md
git add .git commit -m "docs: archive sprint"git push origin docs/archive-sprintNow that you’ve integrated CI/CD:
Validation is Mandatory
Make cortex-tms validate part of every PR and release. Enforcement prevents documentation drift.
Automate Repetitive Tasks
Archive sprints, release versions, and update CHANGELOG automatically. Reduce manual work.
Provide Feedback Early
Pre-commit hooks and PR checks catch issues before they merge. Fast feedback loops improve quality.
Monitor Health Over Time
Track validation metrics, test coverage, and pattern compliance. Use trends to improve process.