Publish To Bitbucket Server

Action ID: publish:bitbucketServer
NPM Package:

@backstage/plugin-scaffolder-backend-module-bitbucket-server

Description

Initializes a git repository of the content in the workspace, and publishes it to Bitbucket Server.

Input Schema

PropertyTypeDescriptionRequired
tokenstringThe token to use for authorization to BitBucket Server
repoUrlstringRepository Location
enableLFSbooleanEnable LFS for the repository.
signCommitbooleanSign commit with configured PGP private key
sourcePathstringPath within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.
descriptionstringRepository Description
defaultBranchstring-
gitAuthorNamestring-
gitAuthorEmailstring-
repoVisibilitystring-
gitCommitMessagestring-

Output Schema

PropertyTypeDescriptionRequired
remoteUrlstringA URL to the repository with the provider
commitHashstringThe git commit hash of the initial commit
repoContentsUrlstringA URL to the root of the repository

Usage Examples

Publish a new private repo with default branch main

Creates a new Bitbucket Server repository from the entire workspace. Uses fetch:template to materialize files and then registers the component with catalog:register.

Copy
steps:
  - id: fetch-skeleton
    action: fetch:template
    input:
      url: https://git.example.com/org/templates/node-service
      targetPath: ./

  - id: publish-bitbucket
    action: publish:bitbucketServer
    input:
      repoUrl: bitbucket.mycorp.example?project=APP&repo=${{ parameters.repoName }}
      description: Node.js service scaffolded via Backstage
      repoVisibility: private
      defaultBranch: main

  - id: register
    action: catalog:register
    input:
      catalogInfoUrl: ${{ steps['publish-bitbucket'].output.repoContentsUrl }}/catalog-info.yaml

Publish only a subdirectory with LFS enabled and custom commit metadata

Publishes only a subfolder of the workspace as the repo root. Useful when your template generates multiple components and you want a dedicated repo with Git LFS for large assets.

Copy
steps:
  - id: fetch-monorepo-template
    action: fetch:template
    input:
      url: https://git.example.com/org/templates/fullstack-app
      targetPath: ./

  - id: publish-service
    action: publish:bitbucketServer
    input:
      repoUrl: bitbucket.mycorp.example?project=WEB&repo=${{ parameters.serviceRepo }}
      description: Frontend service extracted from monorepo template
      repoVisibility: private
      defaultBranch: main
      sourcePath: services/frontend
      enableLFS: true
      gitCommitMessage: "chore(scaffold): initial import of frontend service"
      gitAuthorName: "Backstage Scaffolder"
      gitAuthorEmail: "scaffolder@mycorp.example"

  - id: register-service
    action: catalog:register
    input:
      catalogInfoUrl: ${{ steps['publish-service'].output.repoContentsUrl }}/catalog-info.yaml

Override token and sign the initial commit

Uses an explicit token when integrations are not configured and signs the initial commit. The signing uses the PGP key configured on the runner.

Copy
steps:
  - id: fetch-api-template
    action: fetch:template
    input:
      url: https://git.example.com/org/templates/java-api
      targetPath: ./

  - id: publish-signed
    action: publish:bitbucketServer
    input:
      repoUrl: ${{ parameters.bitbucketHost }}?project=${{ parameters.projectKey }}&repo=${{ parameters.repoName }}
      description: Java API service with signed initial commit
      repoVisibility: private
      defaultBranch: main
      token: ${{ parameters.bitbucketToken }}
      gitCommitMessage: "feat: initial API service scaffold"
      gitAuthorName: "Service Platform"
      gitAuthorEmail: "platform@mycorp.example"
      signCommit: true

  - id: register-api
    action: catalog:register
    input:
      catalogInfoUrl: ${{ steps['publish-signed'].output.repoContentsUrl }}/catalog-info.yaml

Create a public repository on a nondefault branch

Creates a public repository with develop as the default branch. Use this when your team standardizes on a nondefault branch for new services.

Copy
steps:
  - id: fetch-service-template
    action: fetch:template
    input:
      url: https://git.example.com/org/templates/go-service
      targetPath: ./

  - id: publish-develop
    action: publish:bitbucketServer
    input:
      repoUrl: bitbucket.mycorp.example?project=PAY&repo=${{ parameters.repoBase }}-svc
      description: Payments microservice
      repoVisibility: public
      defaultBranch: develop
      gitCommitMessage: "init(payments): scaffold service on develop"

  - id: register-develop
    action: catalog:register
    input:
      catalogInfoUrl: ${{ steps['publish-develop'].output.repoContentsUrl }}/catalog-info.yaml

Publish an infra-only repo from a nested path

Publishes only the infra directory to its own repository. This separates infrastructure code from application code while keeping a single template source with fetch:template.

Copy
steps:
  - id: fetch-platform-template
    action: fetch:template
    input:
      url: https://git.example.com/org/templates/platform-stack
      targetPath: ./

  - id: publish-infra
    action: publish:bitbucketServer
    input:
      repoUrl: ${{ parameters.bitbucketHost }}?project=PLT&repo=${{ parameters.env }}-infra
      description: Terraform modules for ${{ parameters.env }} environment
      repoVisibility: private
      defaultBranch: main
      sourcePath: infra/terraform
      gitCommitMessage: "infra(${{ parameters.env }}): initial Terraform modules"

  - id: register-infra
    action: catalog:register
    input:
      catalogInfoUrl: ${{ steps['publish-infra'].output.repoContentsUrl }}/catalog-info.yaml