Skip to main content
cops uses two separate config files: a user config (config.json) that stores auth profiles, and a project config (cops.project.json) that stores release gate policies for a specific project.

User config

The user config lives at:
PlatformPath
Linux / macOS~/.config/cops/config.json
Windows%APPDATA%\cops\config.json
It is managed entirely by the cops auth commands. You should not edit it by hand. See Auth profiles for the full structure and management commands.

Project config (cops.project.json)

The project config declares your release gate policy — which gates to run, with what parameters, against which Jira project / Confluence space / Bitbucket repo / Bamboo plans.

Creating a config

cops init --template backend-service
By default, cops writes cops.project.json to the global config directory. Use --target local to write it into the current working directory instead:
cops init --template backend-service --target local

Config file precedence

cops looks for cops.project.json in this order and uses the first file found:
  1. COPS_PROJECT_CONFIG environment variable — explicit file path; takes priority over everything else
  2. Global config directory~/.config/cops/cops.project.json (Linux/macOS) or %APPDATA%\cops\cops.project.json (Windows)
  3. Current working directory./cops.project.json
Use COPS_PROJECT_CONFIG=/path/to/my-config.json cops release check --all to target a specific file without moving it or changing the global config.

Full structure

Below is a complete annotated example derived from the built-in template:
{
  "defaultProject": "my-service",
  "projects": {
    "my-service": {
      "jira": {
        "projectKey": "EXAMPLE",
        "fixVersion": "2026-01-01",
        "readyStatuses": [
          "Ready for Release",
          "Done",
          "Closed",
          "Resolved"
        ]
      },
      "confluence": {
        "requiredPages": [
          {
            "spaceKey": "ENG",
            "title": "Service Deployment Playbook"
          }
        ]
      },
      "bitbucket": {
        "releaseBranch": "release/2026-03-13"
      },
      "bamboo": {
        "requiredPlans": [
          "EXAMPLE-PLAN"
        ]
      },
      "gates": [
        {
          "id": "jira-stories",
          "type": "jira-stories-exist",
          "enabled": true,
          "severity": "high"
        },
        {
          "id": "confluence-doc",
          "type": "confluence-page-exists",
          "enabled": false,
          "severity": "high"
        },
        {
          "id": "confluence-sections",
          "type": "confluence-page-sections",
          "enabled": false,
          "severity": "high",
          "params": {
            "requiredSections": ["Deployment Steps", "Rollback"]
          }
        },
        {
          "id": "release-branch",
          "type": "bitbucket-release-branch-exists",
          "enabled": false,
          "severity": "high"
        },
        {
          "id": "bitbucket-open-pr-threshold",
          "type": "bitbucket-pr-checks",
          "enabled": false,
          "severity": "medium",
          "params": {
            "maxOpenToRelease": 0
          }
        },
        {
          "id": "bamboo-plan",
          "type": "bamboo-plan-active",
          "enabled": false,
          "severity": "high"
        },
        {
          "id": "bamboo-latest-build",
          "type": "bamboo-latest-build-success",
          "enabled": false,
          "severity": "high"
        }
      ]
    }
  }
}

Config sections

FieldTypeDescription
defaultProjectstringProject ID to use when --project is not specified on the command line
projectsobjectMap of project ID → project release config
If defaultProject is set and the named project exists in projects, cops uses it automatically. If there is exactly one project defined and defaultProject is absent, cops uses that project by default.
FieldTypeDescription
projectKeystringJira project key (e.g. EXAMPLE)
fixVersionstringTarget fixVersion name (e.g. 2026-01-01)
readyStatusesstring[]Issue statuses that count as release-ready
Gates of type jira-stories-exist resolve projectKey and fixVersion from this section if not overridden in params.
FieldTypeDescription
requiredPagesarrayList of { spaceKey, title } objects
Confluence gates resolve the first entry in requiredPages as the target page if params.spaceKey and params.title are not specified directly on the gate.
FieldTypeDescription
projectKeystringBitbucket project key
repostringRepository slug
releaseBranchstringName of the release branch (e.g. release/2026-03-13)
Bitbucket gates resolve these values from the section unless overridden in params.
FieldTypeDescription
requiredPlansstring[]List of Bamboo plan keys (e.g. ["EXAMPLE-PLAN"])
Bamboo gates resolve the first entry in requiredPlans as the target plan if params.plan is not specified on the gate.
Each entry in gates supports the following fields:
FieldTypeDescription
idstringUnique identifier for this gate within the project (required)
typestringGate type — see full list below (required)
enabledbooleanWhether to run this gate; defaults to true
severitystringlow, medium, high, or critical; defaults to high
ownerstringIndividual or team responsible for this gate
teamstringTeam responsible for remediation
ticketstringTracking ticket reference
slaHoursnumberSLA in hours for remediation
waiverstringWaiver reason; suppresses blocking behaviour if set and not expired
waiverExpiresstringISO datetime after which the waiver no longer applies
paramsobjectGate-specific parameters (see individual gate types)
A gate with severity: high or severity: critical that produces a warn result is treated as blocking. Lower severities produce a non-blocking warning.

Supported gate types

Gate typeWhat it checks
jira-stories-existAt least one Jira issue exists for the configured projectKey + fixVersion
confluence-page-existsA Confluence page with the given space key and title exists
confluence-page-sectionsThe Confluence page body contains all requiredSections headings
confluence-page-freshnessThe Confluence page was last updated within maxAgeDays (default: 14)
bitbucket-release-branch-existsThe configured releaseBranch exists in the Bitbucket repository
bitbucket-pr-checksOpen pull requests targeting the release branch are within the maxOpenToRelease threshold (default: 0)
bamboo-plan-activeThe configured Bamboo plan is enabled and active
bamboo-latest-build-successThe latest build for the Bamboo plan succeeded
checkmarx-scan-thresholdCheckmarx scan results are within the configured High / Medium / Low count thresholds
deployment-freeze-windowThe current time is not inside any configured deployment freeze window
bamboo-multi-env-promotionTwo or more Bamboo deployment environments show the required state in the correct promotion order

Validating your config

After editing cops.project.json, validate it before running gates:
cops release policy validate --project my-service
This checks for duplicate gate IDs, unsupported gate types, missing required params, and invalid values like slaHours or waiverExpires.

Build docs developers (and LLMs) love