Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Code

392 commit(s) on main

Merge change request 01M70WES5ZZDJ6RP226WB11BBZ: Let people rename and remove their own passkeys keenan · 58m ago 4b8c9e1d
source preview history blame raw 4.9 KiB
1# Releases
2
3A release should travel with the code. In Vole, it does: a release is a Git tag
4with a message. The message is the release notes, and the tagged code is the
5source. Both travel with every clone, so there is no separate release database to
6keep in sync.
7
8## Create a release
9
10```sh
11vole release create v1.0.0 -F notes.md
12git push --follow-tags
13```
14
15Plain Git works the same way:
16
17```sh
18git tag -a v1.0.0 -F notes.md
19git push --follow-tags
20```
21
22Use an annotated tag (`git tag -a`). It has a message and a tagger. A lightweight
23tag appears in the release list for completeness, but it has no notes and cannot
24carry release files. `vole release create` refuses to overwrite an existing tag
25and tells you to choose a new name.
26
27## Create a release in the browser
28
29A repository maintainer can create the same annotated tag from **Releases → New
30release**: choose a tag name, a target branch or commit, and write the notes. The
31notes become the tag message and the tagger is the account that submitted the
32form. **Edit notes** changes the message of an annotated tag while the release has
33no files attached; once an artifact is published the release is immutable, and
34the web refuses the edit. Lightweight tags are never editable.
35
36## Download source archives
37
38The `/<repo>/releases` page lists every tag. A release page shows the notes, the
39commits since the previous release, and two generated downloads:
40
41```sh
42curl -O http://host/demo/releases/v1.0.0/archive.tar
43curl -OJ http://host/demo/releases/v1.0.0/archive.tar.gz
44```
45
46Vole builds the archives from the tagged tree when someone requests them, so they
47cannot go stale. The `ETag` is the tag's id, so repeat downloads get a `304`, and
48the same tag produces the same bytes on every instance.
49
50If a repository tracks files with Git LFS, the release page shows a warning.
51`git archive` copies pointer files, not the files themselves.
52
53## Attach release files
54
55Binaries attach over SSH into the shared storage, and Vole records a pointer for
56them:
57
58```sh
59vole release attach v1.0.0 dist/vole-linux-amd64 dist/vole-darwin-arm64
60curl -O http://host/demo/releases/v1.0.0/artifacts/vole-linux-amd64
61sha256sum vole-linux-amd64
62```
63
64Attach files after pushing the tag, not before. The pointer is what publishes the
65file, and Vole refuses a pointer whose file was never uploaded. That way a
66download link never points at nothing.
67
68If you attach the same file twice, Vole stores one copy and the second upload
69transfers nothing. Downloads support `ETag`, `304`, `Content-Disposition:
70attachment`, and Range requests, so large files can resume. Files from a private
71repository return `404`.
72
73## Releases do not change
74
75Once a release has files attached, Vole refuses to move or delete that tag, remove
76a file, or point a file name at different bytes. A saved download keeps meaning
77what it meant.
78
79You can add another file; that does not invalidate anything. An admin can repair a
80mistyped release, and the override is recorded in `data/audit.log`.
81
82Release file pointers live on the `vole` branch, so `vole admin gc --dry-run` treats a
83published release file as something to keep.
84
85## Build a release in CI
86
87A workflow can build and publish a release instead of attaching files by hand:
88
89```yaml
90artifacts:
91 - path: dist/*
92 release: true
93```
94
95The run records the same pointers that `vole release attach` writes, so the
96release page, download behavior, and immutability rules stay the same. See
97[Workflows § Build a release](workflows.md#build-a-release).
98
99## A bill of materials for each release
100
101A release built by the workflow carries an SBOM: `vole-<version>.sbom.cdx.json`,
102in CycloneDX JSON, listed on the release page beside the packages and covered by
103`SHA256SUMS`.
104
105It names every Go module the application links, with the version and hash that
106`go.sum` pins, the Go toolchain, and each module's licence as *detected* evidence
107rather than an asserted conclusion. That is what makes it useful for the question
108it exists to answer: an advisory names a module version, and the SBOM says whether
109the binary you downloaded contains it.
110
111Two limits, stated so nobody reads more into it than is there:
112
113- **One file covers both architectures.** The module graph is the same for
114 `amd64` and `arm64`; only the compiled files differ. Check it with
115 `GOOS=linux GOARCH=arm64 go list -deps ./cmd/vole`.
116- **The system SQLite library is not a Go module.** The SBOM names
117 `github.com/mattn/go-sqlite3`, the binding the build links, not the
118 `libsqlite3-0` version underneath it. That one comes from the package you
119 installed: `dpkg -s vole` or `rpm -q --requires vole`.
120
121To regenerate it for a tag you already have:
122
123```sh
124go run github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@v1.9.0 \
125 app -json -noserial -std -licenses -main cmd/vole -output SBOM.cdx.json .
126```
127
128The only field the tool takes from the clock is `metadata.timestamp`; the workflow
129replaces it with the tag's commit time, so building one tag twice produces the
130same file.
131