Releases
A release is a tagged snapshot of a repository, optionally with attached binary artifacts, tarballs, or other files. Releases appear at frem.sh/<org>/<repo>/releases and provide a stable, human-readable index of what shipped and when. They are separate from the package registry: releases carry versioned source snapshots and build artifacts, while container images and language-ecosystem packages belong in the Package registry.
Creating a release from the UI
- Go to Repository → Releases → New release (
frem.sh/<org>/<repo>/releases/new). - In the Tag field, choose an existing tag or type a new tag name to create one at the target branch or commit. Semantic versioning (
v1.0.0,v2.3.1-rc.1) is recommended. - Set the Release title. This appears as the heading on the releases page.
- Write release notes in the text area. Markdown is supported. Include a changelog summary, breaking changes, upgrade instructions, and contributor credits.
- Attach release assets by dragging files onto the upload area, or clicking Attach binaries. There is no limit on the number of assets; the per-asset size limit is 2 GB.
- Check This is a pre-release for release candidates, betas, or anything not ready for general use. Pre-releases are shown separately in the releases list and are excluded from the “latest release” indicator.
- Click Publish release to make it public immediately, or Save as draft to finish it later. Drafts are visible only to org owners and members with Write or Admin access on the repository.
Creating a release from a workflow
Automate releases by triggering on pushed tags. This is the standard pattern for projects that build binaries in CI and want to attach them to the release automatically.
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: fremforge
steps:
- uses: actions/checkout@v4
- name: Build
run: make build
- name: Create release
uses: https://code.forgejo.org/actions/forgejo-release@v2
with:
direction: upload
release-dir: dist/
token: ${{ secrets.GITHUB_TOKEN }}secrets.GITHUB_TOKEN is a built-in token automatically available to every workflow job. It is scoped to the current repository and has write access to releases in that repo. No setup is required: fremforge provisions it at job start and it expires when the job ends.
The forgejo-release action at direction: upload creates the release (if it does not already exist for the tag) and uploads every file from dist/ as a release asset.
Uploading assets from a workflow: API approach
For full control over the release creation and asset upload steps, call the API directly from a workflow:
# Create the release
RELEASE_ID=$(curl -sSf \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/json" \
-d "{\"tag_name\":\"${{ github.ref_name }}\",\"name\":\"${{ github.ref_name }}\"}" \
https://frem.sh/api/v1/repos/${{ github.repository }}/releases \
| jq -r '.id')
# Upload an asset
curl -sSf \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/octet-stream" \
--data-binary @dist/myapp-linux-amd64 \
"https://frem.sh/api/v1/repos/${{ github.repository }}/releases/${RELEASE_ID}/assets?name=myapp-linux-amd64"Full API reference: POST /repos/{owner}/{repo}/releases in the REST API docs.
Downloading release assets
Public repositories: release assets are publicly accessible without authentication. Download directly from the asset URL shown on the releases page.
Private repositories: a personal access token (PAT) with repo scope is required.
curl -L \
-H "Authorization: Bearer <PAT>" \
https://frem.sh/<org>/<repo>/releases/download/<tag>/<asset-filename>Semantic versioning
Use vMAJOR.MINOR.PATCH tag names. Consistent versioning lets tooling and dependency managers resolve the “latest” release correctly and makes the releases page easier to read for human visitors.
Pre-release identifiers follow the SemVer convention: v1.2.0-rc.1, v2.0.0-beta.3. Tag them as pre-releases in the UI or set "prerelease": true in the API body.
Deleting a release
- Go to Repository → Releases.
- Find the release and click Edit.
- Scroll to the bottom and click Delete release.
Deleting a release removes the release record and all its attached assets. The underlying Git tag is not deleted by this action. To delete the tag as well, go to Repository → Tags and delete it from there, or run git push origin --delete <tag> from a local clone.
Releases and SBOMs
The platform generates an SBOM for every release tag and attaches it as a release asset (e.g. sbom.spdx.json). SBOM generation is on by default, there is no enable step. Both SPDX 2.3 and CycloneDX 1.5 formats are produced.
See Security and supply chain for the full pipeline configuration and SLSA provenance details.
Releases and the package registry
Releases and the package registry serve different purposes:
| Use case | Where it goes |
|---|---|
Versioned source archive (.tar.gz, .zip) | Release asset |
| Pre-built binary or CLI tool | Release asset |
| Container image | Package registry (frem.sh/<org>/<repo>/packages) |
| npm package | Package registry |
| Maven or Gradle artifact | Package registry |
| PyPI-compatible package | Package registry |
Container images and language-ecosystem packages carry their own versioning and discovery mechanisms (image tags, npm install, mvn dependency:resolve). Use the package registry for those so consumers can pull them directly with standard tooling. Releases are for artifacts that humans or scripts download explicitly.
Cross-references
- Package registry, container images, npm, Maven, and PyPI packages
- Security and supply chain, SBOM generation, container scanning, SLSA provenance
- API, releases REST API reference
- CI runners, runner labels and
GITHUB_TOKENpermissions