Publish To GitLab

Action ID: publish:gitlab
NPM Package:

@backstage/plugin-scaffolder-backend-module-gitlab

Description

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

Input Schema

PropertyTypeDescriptionRequired
tokenstringThe token to use for authorization to GitLab
topicsarrayTopic labels to apply on the repository. (deprecated, use settings.topics instead)
repoUrlstring-
branchesarray-
settingsobject-
signCommitbooleanSign commit with configured PGP private key
sourcePathanyPath within the workspace that will be used as the repository root. If omitted or set to true, the entire workspace will be published as the repository. If set to false, the created repository will be empty.
skipExistingbooleanDo not publish the repository if it already exists. The default value is false.
defaultBranchstring-
gitAuthorNamestring-
gitAuthorEmailstring-
repoVisibilitystring-
setUserAsOwnerbooleanSet the token user as owner of the newly created repository. Requires a token authorized to do the edit in the integration configuration for the matching host
gitCommitMessagestring-
projectVariablesarray-

Output Schema

PropertyTypeDescriptionRequired
createdbooleanWhether the repository was created or not
projectIdnumberThe ID of the project
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 GitLab repository with a custom default branch

Creates a private repository under a GitLab group, commits the workspace content with a custom author and message, and registers the component. Use this when bootstrapping a new service from a template using fetch:template and then catalog:register.

Copy
steps:
  - id: fetch-base
    action: fetch:template
    input:
      url: ./skeleton
      values:
        name: ${{ parameters.name }}
        owner: acme

  - id: publish
    action: publish:gitlab
    input:
      repoUrl: gitlab.com?owner=acme&repo=${{ parameters.name }}
      repoVisibility: private
      defaultBranch: main
      gitCommitMessage: "chore: scaffold ${{ parameters.name }} from template"
      gitAuthorName: "Backstage Scaffolder"
      gitAuthorEmail: "backstage@acme.com"

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

Publish to a subgroup with selective sourcePath and signed initial commit

Publishes only a subdirectory of the workspace to a GitLab subgroup, sets repository topics and description, and signs the initial commit. Use this when you scaffold multiple packages and only one should be published.

Copy
steps:
  - id: fetch
    action: fetch:template
    input:
      url: ./monorepo-template
      values:
        name: ${{ parameters.packageName }}
        subgroup: acme/platform

  - id: publish
    action: publish:gitlab
    input:
      repoUrl: gitlab.com?owner=acme/platform&repo=${{ parameters.packageName }}
      repoVisibility: public
      defaultBranch: main
      sourcePath: packages/${{ parameters.packageName }}
      gitCommitMessage: "feat: initial commit for ${{ parameters.packageName }}"
      gitAuthorName: "Scaffolder Bot"
      gitAuthorEmail: "scaffolder-bot@acme.com"
      signCommit: true
      settings:
        description: "${{ parameters.packageName }} service"
        topics:
          - node
          - service
          - platform

  - id: register
    action: catalog:register
    input:
      catalogInfoUrl: ${{ steps.publish.output.repoContentsUrl }}/-/blob/main/catalog-info.yaml

Use a self-managed GitLab host with skipExisting and setUserAsOwner

Targets a self-managed GitLab instance, skips publishing if the repository already exists, and sets the token user as the owner. Use this for idempotent templates that may be re-run.

Copy
steps:
  - id: fetch
    action: fetch:template
    input:
      url: ./service
      values:
        name: ${{ parameters.name }}

  - id: publish
    action: publish:gitlab
    input:
      repoUrl: gitlab.acme.corp?owner=platform&repo=${{ parameters.name }}
      repoVisibility: internal
      defaultBranch: main
      skipExisting: true
      setUserAsOwner: true
      token: ${{ secrets.gitlabToken }}
      gitCommitMessage: "chore: scaffold ${{ parameters.name }}"
      gitAuthorName: "Backstage"
      gitAuthorEmail: "backstage@acme.corp"

  - id: register
    action: catalog:register
    input:
      catalogInfoUrl: ${{ steps.publish.output.repoContentsUrl }}/-/blob/main/catalog-info.yaml

Create additional branches during publish

Creates a repository with a main branch and additional branches seeded from main, with protection on release branches. Use this when your workflow requires predefined long-lived branches.

Copy
steps:
  - id: fetch
    action: fetch:template
    input:
      url: ./template
      values:
        name: ${{ parameters.serviceName }}

  - id: publish
    action: publish:gitlab
    input:
      repoUrl: gitlab.com?owner=acme&repo=${{ parameters.serviceName }}
      repoVisibility: private
      defaultBranch: main
      gitCommitMessage: "chore: initial scaffold"
      gitAuthorName: "Backstage Scaffolder"
      gitAuthorEmail: "backstage@acme.com"
      branches:
        - name: develop
          ref: main
        - name: release/1.0
          ref: main
          protected: true
        - name: hotfix
          ref: main

  - id: register
    action: catalog:register
    input:
      catalogInfoUrl: ${{ steps.publish.output.repoContentsUrl }}/-/blob/main/catalog-info.yaml

Set project-level CI/CD variables on creation

Publishes a new repository and configures GitLab project variables for CI/CD. Use this to inject environment-specific secrets as part of the scaffolding process.

Copy
steps:
  - id: fetch
    action: fetch:template
    input:
      url: ./service
      values:
        name: ${{ parameters.name }}

  - id: publish
    action: publish:gitlab
    input:
      repoUrl: gitlab.com?owner=acme&repo=${{ parameters.name }}
      repoVisibility: private
      defaultBranch: main
      gitCommitMessage: "feat: bootstrap ${{ parameters.name }}"
      token: ${{ secrets.gitlabToken }}
      settings:
        description: "${{ parameters.name }} with CI/CD"
        topics:
          - ci
          - backstage
      projectVariables:
        - key: DATABASE_URL
          value: ${{ parameters.databaseUrl }}
          protected: true
          masked: true
          environmentScope: production
        - key: FEATURE_FLAG
          value: "true"
          protected: false
          masked: false
          environmentScope: "*"

  - id: register
    action: catalog:register
    input:
      catalogInfoUrl: ${{ steps.publish.output.repoContentsUrl }}/-/blob/main/catalog-info.yaml