Deployments triggered from CI pipelines do not update environment tracking in Jira 9

We wired our CI/CD pipeline (GitHub Actions) to post deployment events to Jira 9 using the deployments REST API, but the environment tracking panel in Jira issues remains empty. The pipeline completes successfully with 200 responses from Jira, yet no deployment information appears.

Our GitHub Actions workflow extracts issue keys from commit messages, then posts to /rest/deployments/1.0/deployment with payload including deployment state, environment type, and issue keys. We’re using an API token for authentication and verified the service account has the necessary permissions. The workflow logs show successful API responses but Jira shows nothing.

We’re running Jira 9 on-premises behind a firewall. Not sure if this is a connectivity issue, incorrect API usage, or something with how deployment states and environment types map to Jira’s internal model. Has anyone successfully integrated GitHub Actions deployments with on-prem Jira 9?

Environment types are predefined and don’t need configuration. But the state values are strict-use ‘successful’ for completed deployments, ‘failed’ for failures, ‘pending’ for in-progress, ‘cancelled’ for aborted, ‘rolled_back’ for rollbacks. Anything else gets silently dropped. The API returns 200 because the request format is valid, but Jira won’t create the deployment record.

We tested connectivity and found that was part of the issue-our firewall was blocking some GitHub Actions IP ranges. We set up a self-hosted runner with explicit access to Jira. But we were also using incorrect state values. Fixed both issues and deployments are now appearing. Thanks for the troubleshooting help!

Also check your issue key mapping. If the issue keys in your payload don’t exist or are in a project where the service account lacks permissions, the deployment won’t appear. The API still returns success but the deployment is orphaned. Try posting a deployment for a single known issue key with explicit project permissions to isolate the issue.

Checking our payload now. We’re using state ‘deployed’ which might be the issue. Does Jira’s API documentation list the allowed values somewhere? Also, do the environment types need to be pre-configured in Jira or are they dynamic?

Here’s a comprehensive solution for integrating GitHub Actions deployments with on-premises Jira 9:

Using Jira Deployments REST API Correctly: The deployments API endpoint is /rest/deployments/1.0/deployment (note: no ‘s’ at the end). The payload structure must include:

  • deploymentSequenceNumber: Unique identifier for this deployment (we use the GitHub Actions run number)
  • updateSequenceNumber: Timestamp or incrementing number (we use Unix timestamp)
  • associations: Array of objects with associationType: 'issueIdOrKeys' and array of issue keys
  • displayName: Human-readable deployment name (e.g., ‘Production Deploy #1234’)
  • url: Link back to the GitHub Actions run for traceability
  • description: Deployment details
  • lastUpdated: ISO8601 timestamp
  • state: MUST be one of the allowed values (see below)
  • pipeline: Object with id, displayName, url for the pipeline/workflow
  • environment: Object with id, displayName, type for target environment

Allowed Deployment State Values: Jira only accepts these specific state values:

  • successful: Deployment completed successfully (use this instead of ‘deployed’ or ‘completed’)
  • failed: Deployment failed (use this instead of ‘error’ or ‘unsuccessful’)
  • pending: Deployment in progress
  • cancelled: Deployment was aborted
  • rolled_back: Deployment was rolled back

Using any other value causes Jira to accept the API call (returning 200) but silently discard the deployment. This is the most common issue.

Environment Types: The environment type field must be one of:

  • production: Production environment
  • staging: Staging/pre-production environment
  • testing: Test environment
  • development: Development environment
  • unmapped: Other environments

These are hardcoded in Jira and don’t need pre-configuration. The environment id should be a stable identifier (we use ‘prod’, ‘staging’, etc.), and displayName is what appears in Jira UI.

Mapping Deployment Events to Jira Issues: Extract issue keys from commit messages using regex pattern ([A-Z]+-[0-9]+). Our GitHub Actions workflow parses all commits in the push event, deduplicates the issue keys, then includes them in the associations array:

associations: [
  {
    associationType: "issueIdOrKeys",
    values: ["PROJ-123", "PROJ-456"]
  }
]

If no issue keys are found, we skip posting the deployment to Jira rather than posting an orphaned deployment.

On-Prem Jira Connectivity with GitHub Integration: For on-premises Jira behind a firewall, GitHub’s cloud-hosted runners cannot reach your instance directly. Solutions:

  1. Self-Hosted Runner (our approach): Deploy a GitHub Actions runner inside your network with access to Jira. This runner executes the deployment workflow steps including the Jira API call. Configure the runner to use your internal DNS/network routing.

  2. Reverse Proxy: Set up a public-facing proxy that forwards deployment API calls to internal Jira. This requires careful security configuration and API token management.

  3. Firewall Rules: Allowlist GitHub Actions IP ranges in your firewall. GitHub publishes these ranges in their meta API, but they change frequently, making this approach maintenance-heavy.

We chose the self-hosted runner approach for security and reliability. The runner is deployed as a Kubernetes pod in our cluster with network access to Jira.

Authentication: Use a Jira API token (not password) for the service account. Create a dedicated service account with permissions:

  • Browse Projects permission on all relevant projects
  • Create Attachments permission (required by deployments API)
  • No other permissions needed

Store the API token in GitHub Secrets and reference it in the workflow. Use Basic Auth with username (email) and token as password.

Complete GitHub Actions Example:

- name: Post deployment to Jira
  run: |
    ISSUE_KEYS=$(git log --format=%B -n 20 | grep -oE '[A-Z]+-[0-9]+' | sort -u | jq -R . | jq -s .)
    curl -X POST "${JIRA_URL}/rest/deployments/1.0/deployment" \
      -u "${JIRA_EMAIL}:${JIRA_API_TOKEN}" \
      -H "Content-Type: application/json" \
      -d "{
        deploymentSequenceNumber: ${GITHUB_RUN_NUMBER},
        updateSequenceNumber: $(date +%s),
        associations: [{associationType: issueIdOrKeys, values: ${ISSUE_KEYS}}],
        displayName: Production Deploy #${GITHUB_RUN_NUMBER},
        url: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID},
        state: successful,
        lastUpdated: $(date -u +%Y-%m-%dT%H:%M:%SZ),
        pipeline: {id: ${GITHUB_WORKFLOW}, displayName: ${GITHUB_WORKFLOW}, url: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions},
        environment: {id: production, displayName: Production, type: production}
      }"

Troubleshooting: If deployments still don’t appear:

  1. Check Jira application logs for deployment API errors (usually in atlassian-jira.log)
  2. Verify service account has Browse Projects permission on the target projects
  3. Confirm issue keys in payload actually exist and are accessible
  4. Test with a minimal payload and single known issue key first
  5. Use Jira’s REST API browser (if available) to test the endpoint directly

After implementing these fixes, deployments now appear correctly in Jira’s environment tracking panel, giving our product team visibility into which issues are deployed to which environments without leaving Jira.