Skip to content

Semantic release workflow breaks when push with CI Job token feature is enabled

Problem

Semantic release workflows fail to trigger new pipelines when the "push with CI Job token" feature is enabled in a project. This breaks automated release processes that depend on pipeline triggers after pushing version tags and release commits.

Root Cause

The issue arises during the semantic-release dry run phase. Semantic-release performs a dry run to test push permissions without using the provided GL_TOKEN. This dry run is designed for SSH push scenarios where Git credentials aren't required separately. However, in GitLab CI, the git origin URL by default contains the CI Job token embedded in it.

When the CI Job token has push permissions enabled:

  1. The dry run succeeds using the embedded CI Job token (instead of failing as expected without explicit credentials)
  2. Semantic-release interprets this success as not needing the GL_TOKEN for subsequent operations
  3. Actual pushes then use the CI Job token instead of the provided GL_TOKEN
  4. Pushes authenticated with CI Job tokens intentionally do not trigger new pipelines (as a safety mechanism to prevent infinite pipeline loops)

This creates a conflict for semantic release workflows that:

  • Provide a GL_TOKEN (Personal Access Token) specifically to trigger pipelines
  • Expect their pushes to trigger new pipelines for deployment or further processing
  • Are undermined by the dry run's false positive success with the CI Job token

Current Behavior

  1. Semantic release job runs with CI Job token push permissions enabled
  2. Dry run phase tests push without using GL_TOKEN
  3. Dry run succeeds due to embedded CI Job token in origin URL
  4. Semantic-release skips using GL_TOKEN for actual pushes based on dry run success
  5. git push uses CI Job token for authentication (overriding the provided PAT)
  6. Push is successful but no new pipeline is triggered
  7. Release workflow breaks as dependent processes expecting pipeline triggers fail

Expected Behavior

Semantic release workflows should:

  • Correctly identify when a Personal Access Token (GL_TOKEN) is needed
  • Use the provided GL_TOKEN for pushes even when CI Job token permissions are available
  • Successfully trigger new pipelines when pushing commits/tags with proper authentication

Workaround

Manually configure a custom remote URL that bypasses CI Job token authentication:

git remote set-url origin https://gitlab.com/username/project.git

This forces git to use configured credentials (like PAT) instead of the CI Job token, ensuring the dry run fails appropriately and semantic-release uses the provided GL_TOKEN.

Impact

  • Breaks automated release workflows for projects using semantic-release
  • Affects any CI/CD pipeline that needs to push code and trigger subsequent pipelines

Potential Solution Considerations

  1. Semantic-release side: Modify the dry run logic to account for GitLab CI's embedded token behavior, ensuring GL_TOKEN is used when provided regardless of dry run results

  2. GitLab side: Trigger pipelines with appropriate safeguards

  3. Documentation: Clearly document this interaction between semantic-release dry runs and GitLab's CI Job token to help users understand and avoid this issue

Technical Details

The semantic-release tool performs authentication in two phases:

  • Dry run phase: Tests push permissions without credentials (works for SSH, problematic for GitLab CI)
  • Actual push phase: Uses credentials only if dry run failed

This two-phase approach conflicts with GitLab CI's default git configuration where the origin URL includes: https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/...

Related Issues

Edited by Aboobacker MK