README
¶
Tarbor
A minimal CLI tool for archiving and publishing artifacts to code forges.
Tarbor automates the release workflow: it archives configured artifacts and publishes them as release assets to GitHub, GitLab, Forgejo, or Gitea.
Installation
Build from Source
git clone https://codeberg.org/its-astro/tarbor.git
cd tarbor
go build -o tarbor .
Install with Go
go install codeberg.org/its-astro/tarbor@latest
Quick Start
1. Create a Configuration File
Create tarbor.yaml in your project root:
forge:
platform: forgejo # github, gitlab, forgejo, or gitea
url: https://codeberg.org/owner/repo
token: ${FORGEJO_TOKEN} # supports environment variables
artifacts:
- source: dist/myapp_linux_amd64
format: zip
name: myapp_{{.Version}}_linux_amd64
2. Run the Release Command
tarbor release v1.21.0
This will:
- Validate the version string
- Archive each configured artifact
- Create a release with tag
v1.21.0 - Upload the archives as release assets
Commands
tarbor release <version>
Create a new release with the given version.
| Flag | Short | Description |
|---|---|---|
--config |
-c |
Path to configuration file (default: tarbor.yaml) |
--description |
-d |
Description for the release |
--description-file |
Path to a file containing the release description | |
--dry-run |
Show what would be archived and released without performing any actions | |
--output |
-o |
Write archived artifacts to a directory instead of publishing (disables forge interactions) |
--allow-archives |
Allow archive extensions in the source path | |
--hash |
Generate checksum files for archived artifacts using md5 or sha256 | |
--no-summary |
Do not display a summary before proceeding |
Warning
--dry-rundoes not touch the disk at all, as a result of this it also does not perform checks on whether the configured artifacts exist on disk as these happen during the process of creating the archives themselves.
Examples
# Basic release
tarbor release v1.21.0
# With release description
tarbor release v1.21.0 -d "Bug fixes and performance improvements"
# Read description from file
tarbor release v1.21.0 --description-file CHANGELOG.md
# Dry run (no forge interaction)
tarbor release v1.21.0 --dry-run
# Just archive to local directory
tarbor release v1.21.0 --output ./dist/archives
# Generate MD5 checksums
tarbor release v1.21.0 --hash md5
# Generate SHA-256 checksums
tarbor release v1.21.0 --hash sha256
When --hash is set to md5 or sha256, Tarbor generates a checksum file alongside each archived artifact. The checksum file uses the archive's full filename with .md5 or .sha256 appended, respectively. Each file contains the checksum value and the filename in conformance with the sha256sum and md5sum tools, there is currently no option to create a single hash for all files.
For example, tarbor-1.21.0.tar.gz produces tarbor-1.21.0.tar.gz.sha256 when using --hash sha256.
Note
MD5 is cryptographically broken and should not be used for security-sensitive integrity verification. Use
--hashsha256 unless compatibility with existing tooling requires MD5. Checksums can detect accidental corruption, but they do not verify the authenticity of a release.
Configuration
Forge Configuration
| Field | Type | Required | Description |
|---|---|---|---|
platform |
string | Yes | One of: github, gitlab, forgejo, gitea |
url |
string | Yes | Repository URL (e.g., https://codeberg.org/owner/repo) |
token |
string | Yes | Authentication token. Can reference env vars: ${GITHUB_TOKEN} |
gitlab.token_type |
string | GitLab only | "pat" (default) or "job" for CI job tokens |
Caution
If your forge instance is hosted under a subpath, you may encounter unexpected behaviour when using Tarbor. This is because Tarbor derives the repository owner and name from the URL's path segments, and the resulting behaviour depends on the configured forge implementation.
- GitLab: The subpath will be incorrectly interpreted as part of the owner slug, as the GitLab implementation supports nested repository paths. For example,
https://example.com/gitlab/owner/repowould be interpreted as having an owner slug ofgitlab/ownerinstead ofowner.- GitHub and Forgejo: The URL will be rejected, as these implementations only support URLs containing two path segments.
Support for forge instances hosted under a subpath is planned for a future version, but these setups are not currently supported.
Artifact Configuration
| Field | Type | Required | Description |
|---|---|---|---|
source |
string | Yes | Path to artifact. Should not include format extension |
format |
string | Yes | Archive format: tar.gz, tar.xz, tar.zst, zip |
name |
string | Yes | Output name without extension. Supports {{.Version}} template |
Supported Archive Formats
| Format | Extension |
|---|---|
tar.gz |
.tar.gz |
tar.xz |
.tar.xz |
tar.zst |
.tar.zst |
zip |
.zip |
Example Configuration
forge:
platform: forgejo
url: https://codeberg.org/its-astro/tarbor
token: ${FORGEJO_TOKEN}
artifacts:
- source: dist/tarbor_linux_amd64
format: tar.gz
name: tarbor_{{.Version}}_linux_amd64
- source: dist/tarbor_windows_amd64
format: zip
name: tarbor_{{.Version}}_windows_amd64
Environment Variables
- Configuration keys map to uppercase env vars with
_separators (forge.token→FORGE_TOKEN) - Values can also directly reference env vars using
${VAR}syntax - Env var overrides take precedence over config file values
Container Image
Tarbor provides a minimal CI job image for running in containerized CI environments.
- Latest:
codeberg.org/its-astro/tarbor:latest - Version:
codeberg.org/its-astro/tarbor:v1.21.0(replace with your tag)
This is built using a forked version Kaniko which we build ourselves: https://codeberg.org/its-astro/tarbor-kaniko
Build Locally
buildah build -t tarbor .
Run Locally
podman run --rm -v "$PWD":/work tarbor release v1.21.0
Version Validation
Tarbor enforces strict version string rules to ensure compatibility with git tags and file paths:
- Allowed characters: letters, digits,
.,_,+,-,/ - Cannot start with
-or end with. - Cannot contain
..(double dots) - Cannot start/end with
/or contain// - Parts between slashes cannot start with
.or end with.lock - Maximum length: 255 characters
Note
Versions containing
/will have those characters replaced with-when used in filenames. This prevents rejection by forges that do not allow/in tag-derived filenames and helps prevent possible path traversal when writing to disk.
Artifact Name Validation
Artifact names are validated both before templating and after version substitution:
- Names must be unique within the artifact list (no duplicates)
- Cannot be empty,
.or.. - Cannot contain path separators (
/or\). Since versions may contain/, any such characters in{{.Version}}substitutions are replaced with-before artifact names are validated. - Cannot contain NUL bytes
- After templating (e.g.,
{{.Version}}replaced), the resolved name must also pass all the above checks
This prevents path traversal attacks where a malicious version string could escape the output directory.
License
BSD 3-Clause Clear License. See LICENSE for details.
Documentation
¶
There is no documentation for this package.