weebo-forgejo

Repositories

Create, mirror and protect repositories, give teams access, and add webhooks and deploy keys.

Repositories and what hangs off them (webhooks, deploy keys) are namespaced: they live next to the application that owns them. The allow-list decides which organizations a namespace may use.

KindShort name
ForgejoRepositoryfjrepo
ForgejoWebhookfjhook
ForgejoDeployKeyfjdkey

Before you begin

Create a repository

A repository is created in one of three ways. The choice only applies at creation; changing it afterwards has no effect.

apiVersion: forgejo.weebo.io/v1alpha1
kind: ForgejoRepository
metadata:
  name: app
  namespace: team-a
spec:
  organizationRef: { name: weebo }   # or userRef: { name: alice }
  name: app
  private: true
  init: { readme: Default, license: MIT }

Settings and lifecycle

These fields are kept in sync: description, website, visibility (private), default branch, and units (issues, wiki, pull requests, projects, releases, packages, actions). Leave a unit unset to keep Forgejo's default.

To…Do
RenameChange spec.name. Forgejo keeps a redirect from the old name.
Transfer to another ownerChange organizationRef/userRef and add the forgejo.weebo.io/allow-disruptive-update: "true" annotation.
ArchiveSet archived: true. An archived repository is left untouched until you unarchive it.
DeleteDelete the CR. With the default deletionPolicy: Orphan, the repository stays in Forgejo; set Delete to remove it.

Team access and branch protection

spec:
  teamRefs:
    - name: weebo-devs           # the ForgejoTeam CR's name
  branchProtections:
    - ruleName: main
      enablePush: true
      pushWhitelistTeams: [devs] # the team's name in Forgejo
      requiredApprovals: 1
      statusCheckContexts: [ci/build]

Both lists are authoritative: what isn't listed is removed. Leave branchProtections out to keep the repository's rules as they are (those copied from a template, or set in Forgejo); set it to [] to remove them all.

  • teamRefs grants teams access to the repository. They must belong to the owning organization. The access level comes from the team (see Team access levels). Forgejo always grants the Owners team and teams with includesAllRepositories; the operator leaves those alone.
  • Branch protection allow-lists (pushWhitelistTeams, pushWhitelistUsernames…) use Forgejo names, not CR names, because they're passed to Forgejo as-is. In the example, the CR weebo-devs is the Forgejo team devs.
  • A team only stays in a push allow-list if it has access to the repository. The operator syncs teamRefs first, so listing the team in both places is enough.

Webhooks

apiVersion: forgejo.weebo.io/v1alpha1
kind: ForgejoWebhook
metadata:
  name: app-ci
  namespace: team-a
spec:
  repositoryRef: { name: app }       # or organizationRef for an org-wide hook
  url: https://ci.example.com/hooks/forgejo
  events: [push, pull_request]
  secretRef: { name: app-ci-webhook, key: hmac }

Forgejo signs each delivery with the HMAC secret from secretRef. Things to know:

  • Changing the Secret's value is detected. Forgejo never returns the secret, so the operator tracks a hash of it (status.appliedSecretHash).
  • Some changes recreate the hook. Forgejo's hook edit ignores the secret, httpMethod and any config key it doesn't return. Changing, adding or removing one of them deletes and recreates the hook, which gets a new id and loses its delivery history.
  • The authorization header (authorizationHeaderSecretRef) is edited in place.
  • Both Secrets must be labelled forgejo.weebo.io/credential: "true" (SecretNotAllowed otherwise): Forgejo sends their content to the hook's url, so only a Secret the namespace labelled for that use is read.

Deploy keys

apiVersion: forgejo.weebo.io/v1alpha1
kind: ForgejoDeployKey
metadata:
  name: app-ci
  namespace: team-a
spec:
  repositoryRef: { name: app }
  readOnly: true
  secretTargets: [{ name: app-deploy-key }]
  • Generated key. Without publicKey, the operator generates an ed25519 pair and the Secret gets ssh-privatekey and ssh-publickey, the key names of a kubernetes.io/ssh-auth Secret.

  • Your own key. Set publicKey and the operator only registers it.

  • Rotation. Deleting the Secret, or setting a new value on the forgejo.weebo.io/rotate-secret annotation, generates a fresh pair:

    kubectl -n team-a annotate fjdkey app-ci \
      forgejo.weebo.io/rotate-secret=$(date +%s) --overwrite

To give a user (such as a bot) an SSH key instead of a single repository, use ForgejoUserKey.

Next

Repository templates.

On this page