Publishing to Gitea and Gerrit from Backstage templates

How to scaffold new repositories from Backstage templates into self-hosted Gitea or Gerrit, what changes compared with GitHub or GitLab, and what to verify before teams use it.

On this page

Publishing to Gitea and Gerrit from Backstage templates: what the integration does

If your platform team runs self-hosted Git and wants templates to create repositories there, the scaffolder needs a Git-platform action module and credentials for each system. Gitea and Gerrit need different handling, so one configuration will not cover both. Backstage does not ship a single generic publisher that treats every Git server the same way, and the module you use for each system must be confirmed against the current Backstage action documentation and the vendor documentation before you start building.

Gitea is an MIT licensed, self-hosted service that combines Git hosting, code review, package management and CI/CD, documented at Gitea documentation. Its repository and organization model is close enough to the hosted platforms that a team can often adapt an existing publishing step, but you still need to confirm which action module supports it, which token scopes it needs, and how it behaves with your Gitea version. Gerrit is a separate code review system with its own change model, where work arrives as changes and patch sets rather than as branches with pull requests. Creating a project there and pushing an initial skeleton is a different operation from creating a Gitea repository, so the template's publish step and the follow-up steps (such as code review setup or initial submission) will not transfer one for one.

Before you write any template, ask the people who run each Git server three questions: which Backstage action module they expect you to use, which account and token the scaffolder will hold, and which permissions that account needs to create repositories or projects in the target organization. Record the answers in the template design, because they decide which parts of the GitHub or GitLab examples you can reuse and which you must rewrite. Confirm the Backstage version you run supports the module you choose, since action modules are tied to the framework release line.

What you need before building Gitea or Gerrit publishing

Publishing from a Backstage template to a self-hosted Git platform depends on four things lining up: a supported Backstage release, a supported Node.js runtime, a reachable Git server with a dedicated account, and trust in your internal certificate authority. Check each one before writing any template steps, because failures at the publish step are the hardest to diagnose from the portal.

Supported Backstage release line

Start from the current main release line rather than an old application. The GitHub releases page listed v1.55.3 as the latest release at the time of research, with 1.56.0 in the next release line. Confirm the version your portal runs with yarn backstage-cli versions:bump output before adding a Gitea or Gerrit action module, because the action module must match the @backstage packages in your app. Pin the module version to the same release line.

Node.js 22 or 24 runtime

The versioning policy says Backstage supports exactly two adjacent even-numbered Node.js releases. As of Backstage 1.46.0 these are Node.js 22 and 24. Run the backend on one of these versions in the same image or host that will call the action module, and confirm the supported pair for your Backstage release in the policy before you upgrade Node.js on the portal.

Gitea instance on a supported line

Confirm which Gitea line your organization runs and whether it is in the v28.x series that the release notes cover. Gitea v28.0.0 was released on September 29, 2026 and v28.1.0 on October 6, 2026. Ask your Gitea administrators which database (MySQL, PostgreSQL, SQLite or MSSQL) and which Gitea Actions setting apply, because repository creation and the API behave the same way regardless of backend but your upgrade plan depends on it.

Gerrit version and action module match

Gerrit is not covered by the same supplied facts as Gitea, so record the exact Gerrit server version your team runs and check which Backstage action module release supports it. Do not assume a Gitea-era module works against Gerrit. Ask the module maintainer or your integration owner to confirm the supported Gerrit versions, the REST endpoints it calls and how it authenticates before you write a template step that depends on it.

Dedicated service account and token scope

The scaffolder needs an account that can create repositories in the target organization or project and set initial access, and nothing more. Create a dedicated service account rather than reusing a personal token, record which organizations or groups it may write to, and rotate its credential on a schedule. Confirm in writing with your Gitea or Gerrit administrators which permission the account needs for repository creation, branch setup and group membership.

Network path and internal CA trust

The Backstage backend, not the browser, calls the Git server, so the backend host needs routing and firewall rules to the Gitea or Gerrit API and SSH or HTTPS endpoints. If your Git server uses certificates from an internal certificate authority, add that CA to the trust store the backend process reads, and test with the same Node.js runtime. A certificate error during a publish step will appear as a failed action, so test the connection before the first template run.

What changes in the template compared with GitHub or GitLab

The main change is the publish step. Fetching the skeleton and registering the new component in the catalog usually stay the same, because they work on the rendered files and the catalog descriptor. What changes is the action that creates the repository and the host it targets. Point the publish step at your Gitea host URL and use the Gitea action module in place of the GitHub or GitLab module. Supply a token with permission to create repositories under the target owner or organization. Repository naming rules and visibility options also differ from GitHub and GitLab, so check which visibility values and owner fields the module accepts before you write the parameter form. Confirm the exact parameter names in the action module reference for your Backstage version, not in examples copied from another platform.

Gerrit requires the most rework. Gerrit does not use merge requests or pull requests in the GitHub or GitLab sense. Access is governed by project-level permissions, and every change moves through change review. A template that creates a Gerrit project needs deliberate choices about the parent project, the initial access rights and who may approve changes. Any template step that updates an existing repository should expect to submit changes for review instead of opening a merge request. Ask your Gerrit administrators which project-creation and push permissions the service account needs, and test those rights with a dry run before any developer runs the template.

Continuous integration is the third difference. Gitea Actions is designed to be compatible with GitHub Actions, so workflow files written for GitHub often need only small changes, but you should verify each workflow against your Gitea version. Forgejo Actions is designed to feel familiar to GitHub Actions users but is not compatible with it. If your organization runs Forgejo, treat the workflows committed by templates as new code: rewrite them, run them on your runners and check their labels. In both cases, review the CI files in each skeleton so that the first commit to a new repository runs successfully.

How to configure Gitea and Gerrit publishing step by step

This sequence takes a Backstage instance from no source control integration to a pilot template that creates a repository on a self-hosted Gitea or Gerrit server and registers it in the catalog. Each step closes with a check so the team knows it can move on. Complete it in a sandbox organization first, then promote the same pattern to production.

  1. Create a dedicated service account on the platform

    The platform administrator creates a separate bot account on the Gitea or Gerrit server, not a personal account, and grants it only the rights needed to create repositories in one sandbox organization or project. For Gitea, this is an organization where the account can create repositories. For Gerrit, it is a project or parent project with permission to create projects and set initial access rights. Confirm the exact permission names in the current Gitea and Gerrit documentation for your version, since the rights model differs between them. Check: log in as the bot account and create one empty test repository or project by hand. If that fails, the template will fail for the same reason.

  2. Generate a scoped token and store it in Backstage secrets

    Generate an access token for the service account with the narrowest scope that allows repository creation, and record its expiry and owner in your secrets inventory. Store the token in your secret store and expose it to the Backstage backend as an environment variable, for example through your deployment's secret mechanism, rather than writing it into app-config.yaml. Do not place it in a template parameter or a catalog file. Check: start the backend with the variable set and confirm it loads without the token value appearing in logs or the config endpoint.

  3. Add the host to the integrations configuration

    In the backend configuration, add an entry under integrations for your Gitea or Gerrit host, referencing the environment variable that holds the token. The host value must match the URL that templates will use exactly, including the scheme and any non-default port. Set the same host in any reader configuration you rely on so catalog and skeleton fetches resolve. Check: restart the backend and confirm the integration appears in the loaded configuration with the token redacted, and that the backend starts without integration errors.

  4. Install and register the matching action module

    Install the scaffolder action module that matches your platform in the backend package, then register it in the scaffolder backend alongside the built-in actions. Install only one module per platform and confirm its package name against the Backstage plugin catalog for your release, because community modules change repositories over time. Restart the backend and confirm the action is listed among available actions. Check: open the actions list in the scaffolder page or query the actions endpoint, and confirm the Gitea or Gerrit publish action appears with its input schema.

  5. Write a pilot template that targets the sandbox

    Create a minimal template.yaml with one parameter for the repository name and one for the owner, then use the platform's publish action with a repoUrl pointing at the sandbox organization or project. Keep the skeleton tiny, with a README and a catalog-info.yaml, so failures are easy to read. Set the repository owner and visibility explicitly rather than relying on defaults. Check: run a dry run from the scaffolder UI and confirm every step completes without writing to the platform, and that the rendered skeleton contains the expected catalog-info.yaml.

  6. Run the template and inspect the created repository

    Run the pilot template for real against the sandbox, using a throwaway name. Open the task log and confirm each step, including the publish step, reports success. Then sign in to Gitea or Gerrit as a user who has read access and confirm the repository or project exists with the expected initial content and access rights. For Gerrit, also confirm the initial branch and that the bot account can push a change through the usual review flow. Check: the repository is visible in the platform UI and the task output links to the correct URL.

  7. Register the output in the catalog and verify

    Add a register step to the template so the new component's catalog-info.yaml is added to the catalog, using the repository URL the publish step returns. Run the template once more so a new Component entity is created. Confirm the entity page links back to the repository and that its owner resolves to a known group. Check: the Component appears in the catalog with the correct source location, and it is listed under its owner. Once this passes in the sandbox, repeat the same pattern against your production organization with reviewed credentials.

How template parameters and identities map to Gitea and Gerrit

This table shows how each template field and Backstage identity lands on a Gitea organization, user, or Gerrit project and access group. Read each row as a decision to settle before the first template run, since Gitea and Gerrit model ownership differently and the mapping is hard to change later. The main takeaway is that one canonical Backstage user should map to one platform account on each system.

Field or identityGiteaGerrit
Owner or group parameterMaps to a Gitea organization or a user account; the action needs the target owner to exist and the token to have rights thereMaps to a Gerrit project prefix or parent project; the group must exist in Gerrit's group list before the template runs
Repository name parameterBecomes the Gitea repository name under the chosen owner; confirm name rules and collision handling in your versionBecomes the Gerrit project name, which is usually a path-like string; agree a naming pattern with the Gerrit administrators first
Visibility parameterMaps to private or public repository settings; confirm whether internal visibility is offered in your Gitea versionGerrit projects are readable by groups granted read access; visibility is set through project access rules, not a single flag
Default branch parameterSets the repository default branch on creation; confirm the action supports the parameter in your releaseGerrit uses refs such as the branch under refs/heads; the branch must be created or inherited from the parent project
Owner entity referenceShould resolve to the Backstage Group or User that owns the Component, and is recorded as the owner in the catalog, not in GiteaShould resolve to the same owner group that is granted push and submit rights in the Gerrit project
Backstage user to platform accountOne Backstage user entity should map to one Gitea account, linked through the sign-in resolver, so the action acts as the person who ran the templateOne Backstage user entity should map to one Gerrit account, with the same resolver logic and an SSH key or HTTP credential on file
Token or service accountA bot account or personal access token used by the action needs organization creation and repository rights; scope it to the target ownersA service user with rights to create projects and manage groups is usually required; restrict it to the parent project tree
Access group creationTeams inside the organization control write access; map Backstage groups to Gitea teams in a documented, reviewed listGerrit groups and project owner rules control review and submit; create the group before the project so access resolves on creation

Credentials and placement for Gitea versus Gerrit

Gitea publishing usually runs under a dedicated account whose access token the scaffolder uses to create repositories, set options and push the initial commit. The token's scope decides what a template can do, so the goal is the narrowest set of permissions that lets the action complete. Confirm the exact scope names in the Gitea documentation for your release line, because the names and their grouping change between versions.

  • Dedicated bot account: Create a service user for Backstage rather than reusing a personal token, so audit logs and revocation stay separate from people.
  • Repository scope only: Grant the token the repository write permission needed to create and populate repositories, and avoid administrative or user-management scopes.
  • Organization membership: The account must be a member of the target organization with rights to create repositories there, which is the main placement control.
  • Token storage: Store the token in your secrets store and inject it into the Backstage backend configuration, never in the template repository.
  • Rotation plan: Record who owns the token and how it is rotated, since a scaffolder run fails silently when a token expires.

Before writing scope names into configuration, check them against the Gitea documentation for the version you run.

Securing scaffolder publishing to self-hosted Git

A scaffolder that creates repositories on Gitea or Gerrit holds write credentials to your source control, so it needs the same controls as any automation with that reach. The cards below cover the credential, template, host and audit decisions that determine how far a compromised template or session can reach.

Least-privilege service accounts

Create a dedicated Git account for the scaffolder instead of reusing a personal or administrator token. Grant it only the rights needed to create repositories in the target organizations or projects, and confirm it cannot change server settings, manage other users or push to protected branches. Review its group memberships each time you add a new publishing destination. Ask your Git platform team to confirm which permission model the chosen version applies to repository creation.

Tokens kept out of templates

Keep the Git access token in the Backstage backend configuration sourced from your secrets store, never in template.yaml, skeleton files or catalog descriptors. Templates are readable by anyone who can open the catalog, so a token placed there is effectively published. Rotate the token on a schedule you define and confirm the backend fails closed when the secret is missing.

Restricting who runs repository templates

Limit which templates can create repositories to the teams that own them, using the Backstage permission framework for templates and actions. Decide who may register new Template entities, because a new template with a publish step is a new path to create repositories under your service account. Document the approval step for template changes so the reviewer checks the target host and organization in each publish action.

Allowlisting Git hosts and organizations

Configure the scaffolder so publish actions can reach only the Gitea or Gerrit base URLs you operate, and confirm that a template cannot redirect a request to another host through a parameter. Pin each template to a named organization or project rather than accepting free text. Review the integration configuration whenever you add a host, since an extra entry widens the set of places the token is sent.

TLS with internal certificate authorities

Serve Gitea and Gerrit over HTTPS with certificates from your internal CA, and make the Backstage backend trust that CA through its configured certificate bundle rather than by disabling verification. Disabling TLS checks to get a publish step working sends tokens over unverified connections. Confirm certificate expiry is monitored for both the Git host and the Backstage backend, because a lapsed certificate will stop every template that publishes.

Auditing created repositories and sign-in

Record which user ran each template, which repository it created and which service account performed the call, then compare that record with the repositories that exist on the Git host. Gitea Enterprise lists audit logging as a paid feature, so confirm whether your edition provides it before relying on it. Also disable guest access in Backstage production and map every sign-in provider to one identity, so each publish is attributable to a named person.

Common failures when publishing to Gitea or Gerrit

This table lists the failures teams most often hit when a Backstage template publishes to self-hosted Gitea or Gerrit, with the likely cause and fix for each. Items that depend on the action module behavior say what to confirm in its release notes before changing configuration. Most failures trace to credentials, certificate trust and permissions, which a dry run does not exercise.

FailureLikely causeFix and what to confirm
Authentication rejectedThe token lacks write scope for the target organization, or belongs to an account without rights there.Issue a token from the service account with write access to the target organization. Confirm required scopes in the action module release notes.
Certificate errors from internal CAThe host serves a certificate from an internal CA that the Backstage backend does not trust.Add the CA bundle to the backend trust store and confirm the action module uses it. Do not disable TLS verification.
Repository name collisionA repository with the same name already exists in the owner or project, often from an earlier run.Check for the name before creating, validate names with a fixed pattern, and confirm how the action reports an existing repository.
Wrong host URL in integrationsThe integrations config uses a different host, scheme, port or path than the instance the action calls.Match the host value in app-config to the exact base URL of the Gitea or Gerrit instance. Confirm the expected format in the action module release notes.
Gerrit project creation blockedThe service account lacks create-project rights on the parent namespace, or the parent restricts project creation.Grant create-project rights on the parent to the service account. Confirm the permission model with your Gerrit administrators.
Dry run passes, live run failsDry run skips external calls, so token scope, network reach, names and permissions go untested.Run a live test against a sandbox organization or project with a throwaway name. Confirm which calls the action skips during dry run.

Questions teams ask before publishing to Gitea or Gerrit

What drives the cost of publishing Backstage templates to Gitea or Gerrit?

The main drivers are whether a maintained action module exists for your platform, how many templates must publish to it, how credentials are modeled, and how deep the testing goes. Gitea templates usually need a custom or community action if the built-in set does not cover your steps, while Gerrit work adds change-based review, so the template must create changes and handle votes rather than plain branch pushes. Each template is a separate unit of design, testing and review. Ask any quote to itemize the action module work, per-template effort, credential setup and dry-run testing, and to state which parts are one-time and which recur when Backstage or the Git platform upgrades.

How long does a Gitea or Gerrit publishing project take?

Duration depends on scope rather than on the platform name alone. The variables are the number of templates, whether each needs a custom scaffolder action, how much of the Gerrit review workflow the template must reproduce, and how quickly the platform team can provide accounts, network paths and certificates. A small set of templates on an existing Gitea instance with supported actions is a much smaller job than a Gerrit estate with several custom actions and a sandbox that must be built first. DeployOpen agrees timelines in writing as part of a fixed-scope engagement, so ask for a schedule tied to named deliverables.

What does the platform team need to provide before the work starts?

Expect to supply a test Gitea or Gerrit instance separate from production, service accounts with the narrowest scopes that can create repositories or changes, and network routes from the Backstage backend to the Git server. If the Git server uses an internal certificate authority, the Backstage backend must trust that chain, so the team needs to provide the CA bundle and confirm hostnames. You will also need a group or project structure where new repositories will live, and a decision on who owns the template repositories. Confirm each item with your own platform team early, because access requests are often the longest lead item.

Can an internal team publish Backstage templates to Gitea or Gerrit alone?

Yes, a capable internal team can do it, provided it has someone who writes TypeScript for the Backstage backend, someone who administers the Git platform, and time to test. The harder parts are usually the custom actions for Gerrit change handling and the credential model, which need security review. Teams that choose to build internally should still plan dry-run tests, a review process for templates and a way to keep action modules aligned with each Backstage release. A partner is most useful when the internal team lacks Backstage plugin experience or needs the work finished within a fixed window.

What should a fixed-scope quote for Gitea or Gerrit publishing include?

A useful quote lists the Git platform version and deployment model, the named templates in scope, the action modules to be used or built, the credential approach, the test environments, and the acceptance criteria for each template. It should state what is excluded, such as migrating existing repositories, changing Gerrit project policy, or operating the Git server. Ask how dry-run testing is performed, who reviews the templates, what documentation is delivered, and what happens if the Backstage version changes during the project. Fixed scope is agreed in writing before work starts, so every item you care about belongs in that document.

How does Gitea Enterprise or Forgejo change the publishing work?

Gitea Enterprise is a commercial edition from CommitGo, Inc. that adds SAML 2.0 service provider support, audit logging, organization-level branch protection inheritance, IP allowlisting, mandatory two-factor authentication and dependency scanning. Those features affect the access model and audit evidence your templates can rely on, but they do not remove the need to design the publishing flow. Forgejo is a community fork that is licensed GPL-3.0-or-later from v9.0 onward and uses Forgejo Actions, which is not compatible with GitHub Actions. Confirm with the platform vendor which edition you run, because the licensing and feature set determine the template credentials and audit story you can document.

What breaks most often when templates publish to Gitea or Gerrit?

The most common failures are token scopes that are too narrow for repository creation, certificate chains the Backstage backend does not trust, and repository names that collide with existing ones. In Gerrit, templates that push directly rather than creating changes can bypass the review expectations teams rely on, and project-level permissions can block the service account silently. Test each failure path in the sandbox and confirm error messages are readable on the task page. Plan a rollback for partially created repositories, since a failed run can leave artifacts behind that need manual cleanup.

Is a Gerrit template different from a GitHub or GitLab template?

Yes. A GitHub or GitLab template usually creates a repository and pushes an initial commit to the default branch, while Gerrit expects work to arrive as changes that go through review and voting before merge. The template therefore needs a step that creates the project, sets its access rules and submits the initial content as a change. Gitea sits closer to GitHub and GitLab in its pull request model, but its built-in Gitea Actions are designed to be compatible with GitHub Actions, so workflow files may need fewer changes. Confirm each platform's API behavior against its documentation during design.

How DeployOpen scopes and delivers Gitea and Gerrit publishing

Most DeployOpen engagements are fixed-scope, which means the scope, deliverables and timeline are agreed in writing before any build work starts. For a Gitea or Gerrit publishing job, that document should name the platform and version, the hosting model, the Backstage version in use, and each action module the templates will call. It should also state who creates the service accounts and tokens, where repositories will be placed, and which catalog entries are registered on success. The written scope is the reference point when a later question arises about whether something was included.

  • Platform and version: Name the Gitea or Gerrit release line you run, and confirm it with your platform owner before the scope is drafted.
  • Action modules: List the exact publishing actions each template uses, so nothing is assumed about GitHub or GitLab behavior.
  • Responsibilities: Record who provisions credentials, who approves template changes and who owns the resulting repositories.
  • Exclusions: Write down what is out of scope, such as Gerrit label policy redesign or Gitea Actions pipeline authoring.
  • Acceptance criteria: Agree how a successful run is judged, for example a repository created, a catalog entry registered and a clean dry run.

Ask for the written scope to be reviewed by your security and platform leads before signing, since credential scope is often the item that changes most during review.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.