Skip to content

Releases: Nettechnologys/plombir-git

Plombir Git v0.2.0

Choose a tag to compare

@github-actions github-actions released this 17 Oct 11:24

Plombir Git v0.2.0

Push mirrors, Git LFS over SSH, shallow clones for older clients, organization
and instance webhooks with Slack, Discord and Matrix formats, code, pull
request and user search, blame, a first-administrator setup token, opt-in
storage quotas and CI secrets scoped to environments. The release also closes
a set of security issues in authentication, organization rights, mirrors, CI
and the Git protocol, and changes defaults in ways an existing instance has to
check before it upgrades.

CHANGELOG.md lists every change. This
page lists what to do about them.

Before you upgrade

Work through this list on the running v0.1.1 instance, before the new image
starts.

  1. Back up the database and repository storage. Fifteen migrations run on
    the first start, and an older binary may not understand a database the new
    one migrated. File-backed SQLite migrations run while the server is
    stopped; follow the offline migration procedure in deploy/README.md.

  2. Stop or drain external runners. A job an external runner picked up
    before the upgrade has no encrypted snapshot of the secrets it was issued,
    and the new server answers every log upload of such a job with 500. Let
    running jobs finish, stop plombir-git-runner, migrate, then start the
    runners on the v0.2.0 binary: the image: check, the -- separator, the
    environment allow-list and --init live in the runner. Runner hosts need
    Docker 20.10 or newer (docker run --pull never).

  3. docker-compose.hostdir.yml mounts the root filesystem read-only.
    Everything the server writes has to be under /data. Check that the
    mounted plombir-git.toml sets [server].host_key = "/data/ssh_host_key"
    (the template does). Without it the server falls back to $HOME/.ssh,
    cannot write the SSH host key or the at-rest key beside it, and does not
    start. A [logging].file or any other writable path outside /data fails
    the same way.

  4. Registration is closed unless the config says otherwise. An instance
    that sets neither [auth].registration nor PLOMBIR_GIT_REGISTRATION
    refuses new sign-ups once it has an account. Set it explicitly to the
    behaviour you want.

  5. jwt_secret must be at least 16 characters, or the server refuses to
    start.

  6. Webhooks. Find hooks whose content_type the new server refuses:

    SELECT id, content_type FROM webhooks
    WHERE content_type NOT IN ('json', 'form', 'slack', 'discord', 'matrix');

    Each row returned fails every delivery after the upgrade until the hook is
    edited. Receivers of form hooks now get payload=<url-encoded JSON> and
    must decode it.

  7. CI OIDC trust policies. The sub claim is now
    repo:<owner>/<name>:ref:<ref> (or :environment:<env>). Rewrite cloud
    trust policies that match the old repo:<id>:* before the upgrade, or the
    token exchange fails. See docs/ci.md#oidc-tokens.

  8. Admin automation. POST /admin/users,
    POST /admin/users/{id}/password-reset, PATCH /admin/users/{id},
    POST /admin/sso/providers and PATCH /admin/sso/providers/{id} refuse a
    personal access token and need a session in sudo mode. So does creating
    any key, token, passkey, SSO link or runner token.

  9. Browser origin. Cookie-authenticated writes from a foreign Origin
    are refused with 403. Make sure [server].external_url is the address
    people browse, and list a separate frontend origin in
    PLOMBIR_GIT_CORS_ORIGINS.

  10. New limits that are on by default. [mirror].max_clone_size_mb and
    [imports].max_clone_size_mb stop a mirror or import that would write
    more than 10 GiB (Git and LFS together); raise them first if you mirror
    larger repositories. Anonymous GET /api/v1/search is limited to 60
    requests a minute per client; behind a reverse proxy set
    [rate_limit].trusted_proxies, or every anonymous visitor shares one
    budget.

  11. OCI garbage collection starts on its own within an hour of the
    upgrade and cannot be switched off: blobs no manifest references and
    stored objects with no database row are deleted once they are 24 hours
    old. Take a storage backup first if any of those bytes matter.

  12. Reverse proxy. Re-copy deploy/Caddyfile.example or
    deploy/nginx.conf.example, or add a rule that answers 404 for
    /metrics, unless [observability].metrics_token is set.

  13. OIDC over plain HTTP. A provider whose authorization endpoint is
    plain HTTP on a remote host must be listed in
    [auth].allow_insecure_oidc_origins, or sign-in fails.

  14. [logging].max_size_mb. A config that sets it now gets size rotation
    of [logging].file (<file>.1, .2, …) instead of daily files, and 0
    refuses to start. Old daily archives are not cleaned up.

What changes for clients

  • Commit statuses need the full 40-character sha; an abbreviated one is
    400.
  • Pull mirrors need repository administration. Collaborators with write
    access lose the mirror settings and Sync. A mirror URL changed to another
    host needs its credential again (or an empty password).
  • MySQL: a repository address resolves only as its rows spell the owner
    and the name; another spelling is 404 everywhere except the container
    registry. Fix remotes and links that use another case.
  • Case-insensitive names. Owner names and repository names (per owner)
    are unique regardless of case. Pairs that already exist are kept, and
    startup logs a warning naming them; rename one of each pair.
  • CI job variables with a name that is not a valid environment variable
    name refuse the pipeline at trigger time. AWS_*, CLOUDSDK_* and
    GOOGLE_APPLICATION_CREDENTIALS now reach the job container, and a job's
    private image is pulled with the runner operator's Docker credentials, never
    with credentials the job sets.
  • ?state= on issue, pull request and milestone listings: all lists
    everything, an unknown value is 400 instead of an empty list.
  • Field lengths: titles over 255 characters, bodies over 65 536 and
    similar values are 400 on every backend.
  • TLS: outbound connections use rustls, which speaks TLS 1.2 and 1.3
    only. A webhook receiver, mirror source or LDAP server limited to TLS 1.1 or
    older can no longer be reached.
  • Swagger UI is gone from /api-docs. The OpenAPI document stays at
    /api-docs/openapi.json.
  • Anonymous search (type=users) lists active accounts by username and
    display name.

Database migrations

Migration Backends What it does
m20261011_000001_runner_job_mask_snapshot all Adds pipeline_jobs.mask_secrets_encrypted.
m20261011_000002_ci_secrets_mysql_longtext MySQL ci_secrets.encrypted_value becomes LONGTEXT.
m20261011_000003_webhook_scopes all Adds webhooks.scope_kind and scope_id, backfilled for repository hooks.
m20261012_000001_webhook_delivery_mysql_longtext MySQL Delivery request and response bodies become LONGTEXT. Rebuilds the table, which takes a while on a large delivery journal.
m20261012_000002_webhook_secret_mysql_longtext MySQL webhooks.secret_encrypted becomes LONGTEXT.
m20261012_000003_webhook_url_events_mysql_text MySQL webhooks.url and events become TEXT.
m20261012_000004_sso_secret_columns_text MySQL, PostgreSQL SSO client secret and LDAP bind password columns become TEXT.
m20261012_000005_remote_addresses_mysql_text MySQL Mirror and import URLs and the mirror username become TEXT.
m20261014_000001_owner_names_fold_case all Adds a case-folded key and a unique index for owner names. Existing case collisions are kept: one holder gets the key, startup warns about the others.
m20261014_000002_ci_secret_environments all Adds ci_secrets.environment_id; existing secrets stay repository-wide. On SQLite the table is rebuilt in one transaction, and up refuses while a leftover ci_secrets_pre_environment_scope table exists. down refuses while an environment-scoped secret exists.
m20261014_000003_org_owner_role_backfill all Gives every organization without an owner-role member that role for its owner_id account, with an org.owner_role_backfill audit entry.
m20261014_000004_repositories_name_fold_case all Adds a case-folded repository name key and a unique index per owner. The younger repository of each existing case pair is exempted and named at startup.
m20261015_000001_create_push_mirrors all Creates push_mirrors.
m20261016_000001_free_text_columns_mysql MySQL Widens bodies, logs, scripts and list columns to MEDIUMTEXT or TEXT. Rebuilds each table, which takes a while on large pipeline_jobs and issues tables and holds metadata locks.
m20261016_000002_pipeline_job_image_mysql_text MySQL pipeline_jobs.image becomes TEXT.

None of them refuses on existing data, apart from the leftover staging table
named above. The column widenings have a no-op down, so a rollback keeps the
wider columns. On MySQL, objects in the container registry stored under
another spelling of a repository's owner move to the row's spelling at
startup; a failed move is logged and retried at the next start.

Image and runtime

  • The image's entrypoint is tini --. docker run <image> plombir-git … and
    compose command: work as before. A deployment that replaces the
    entrypoint (compose entrypoint:, docker run --entrypoint, a Kubernetes
    command:) runs without tini; on Kubernetes use args: to keep it.
  • CI job containers start with docker run --init, which needs the
    docker-init binary Docker Engine ships. Their names gain a random suffix:
    plombir-git-job-<job>-<random> and plombir-git-runner-job-<job>-<random>.
  • Every smart-HTTP and LFS request writes a...
Read more

Plombir Git v0.1.1

Choose a tag to compare

@github-actions github-actions released this 11 Oct 08:15

Plombir Git v0.1.1

First published release of the server, runner, and MCP stdio binary. The
v0.1.0 tag did not produce a GitHub release because its publication workflow
failed after building the architecture images. This release fixes that workflow
and includes Linux x86_64 and aarch64 binary archives with the built web UI,
an SPDX JSON image SBOM for each architecture, a source dependency SBOM (which
also includes build and dev dependencies), and a multi-architecture image in
GHCR. The image and binary archives have GitHub build provenance attestations.

Upgrade and rollback

Back up the database and repository storage before upgrading. File-backed
SQLite migrations run while the server is stopped; see the offline migration
procedure in deploy/README.md. Check the migration path before switching the
image, and test a restore before relying on rollback: an older binary may not
understand a database migrated by a newer one. Pin the image by digest for a
repeatable deployment; the moving latest tag is not a rollback reference.

The standalone binaries are linked against the Debian bookworm runtime used by
the image. For a host with different system libraries, run the published image.