v0.32.0 53e25a3

release.go RawHistoryFolder

1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package ports
4
5import (
6	"bnema.dev/ermite/internal/domain"
7	"context"
8	"io"
9)
10
11// ReleaseWrite atomically changes one repository's metadata. Every write
12// requires UsageVersion (zero requires absence), and each record's Version.
13// Used includes both uploading and uploaded assets.
14type ReleaseWrite struct {
15	Repo                        domain.RepoName
16	Used                        int64
17	UsageVersion                uint64
18	PutReleases, DeleteReleases []domain.Release
19	PutAssets, DeleteAssets     []domain.ReleaseAsset
20}
21
22// ReleaseStore keeps metadata, never contents. *kvstore.Releases implements it.
23type ReleaseStore interface {
24	NextReleaseID(ctx context.Context) (int64, error)
25	ReleaseUsage(ctx context.Context, repo domain.RepoName) (used int64, version uint64, err error)
26	GetRelease(ctx context.Context, repo domain.RepoName, id int64) (domain.Release, error)
27	GetReleaseByTag(ctx context.Context, repo domain.RepoName, tag string) (domain.Release, error)
28	ReleaseRepo(ctx context.Context, id int64) (domain.RepoName, error)
29	ListReleases(ctx context.Context, repo domain.RepoName) ([]domain.Release, error)
30	GetAsset(ctx context.Context, id int64) (domain.ReleaseAsset, error)
31	GetAssetByName(ctx context.Context, repo domain.RepoName, releaseID int64, name string) (domain.ReleaseAsset, error)
32	ListAssets(ctx context.Context, repo domain.RepoName, releaseID int64) ([]domain.ReleaseAsset, error)
33	AllAssets(ctx context.Context) ([]domain.ReleaseAsset, error)
34	ApplyReleases(ctx context.Context, w ReleaseWrite) error
35}
36
37// ReleaseLimits defaults to domain.DefaultReleaseAssetMax (ERMITE_RELEASE_ASSET_MAX),
38// domain.DefaultReleaseAssetsMax (ERMITE_RELEASE_ASSETS_MAX), and
39// domain.DefaultReleaseQuota (ERMITE_RELEASE_QUOTA).
40type ReleaseLimits struct{ AssetMax, AssetsMax, Quota int64 }
41type CreateReleaseParams struct {
42	Tag, TargetCommitish, Title, Notes string
43	Draft, Prerelease, MakeLatest      bool
44}
45type UpdateReleaseParams struct {
46	Tag, TargetCommitish, Title, Notes *string
47	Draft, Prerelease, MakeLatest      *bool
48}
49
50// ReleaseRef selects exactly one of ID, Tag, Latest.
51type ReleaseRef struct {
52	ID     int64
53	Tag    string
54	Latest bool
55}
56
57// AssetRef selects ID, (Tag, Name), or (Latest, Name).
58type AssetRef struct {
59	ID        int64
60	Tag, Name string
61	Latest    bool
62}
63type UploadAssetParams struct {
64	ReleaseID                int64
65	Name, Label, ContentType string
66	Size                     int64
67	Replace                  bool
68}
69type UpdateAssetParams struct{ Name, Label *string }
70type ReleaseUsage struct {
71	Used   int64
72	Limits ReleaseLimits
73}
74type AssetChunk struct {
75	Asset *domain.ReleaseAsset
76	Data  []byte
77}
78type ReleasePage struct {
79	Releases      []domain.Release
80	NextPageToken string
81}
82
83// ReleaseService manages releases and streams assets; *usecase.Releases implements it.
84type ReleaseService interface {
85	CreateRelease(ctx context.Context, p domain.Principal, repo domain.RepoName, params CreateReleaseParams) (domain.Release, error)
86	GetRelease(ctx context.Context, p domain.Principal, repo domain.RepoName, ref ReleaseRef) (domain.Release, error)
87	ListReleases(ctx context.Context, p domain.Principal, repo domain.RepoName, pageSize int, pageToken string) (ReleasePage, error)
88	UpdateRelease(ctx context.Context, p domain.Principal, repo domain.RepoName, id int64, params UpdateReleaseParams) (domain.Release, error)
89	DeleteRelease(ctx context.Context, p domain.Principal, repo domain.RepoName, id int64) error
90	ListAssets(ctx context.Context, p domain.Principal, repo domain.RepoName, releaseID int64) ([]domain.ReleaseAsset, error)
91	UploadAsset(ctx context.Context, p domain.Principal, repo domain.RepoName, params UploadAssetParams, body io.Reader) (domain.ReleaseAsset, error)
92	UpdateAsset(ctx context.Context, p domain.Principal, repo domain.RepoName, assetID int64, params UpdateAssetParams) (domain.ReleaseAsset, error)
93	DeleteAsset(ctx context.Context, p domain.Principal, repo domain.RepoName, assetID int64) error
94	GetAsset(ctx context.Context, p domain.Principal, repo domain.RepoName, ref AssetRef) (domain.ReleaseAsset, error)
95	// DownloadAsset sends metadata first, then chunks at most domain.CIArtifactChunk;
96	// length less than zero reads to the end.
97	DownloadAsset(ctx context.Context, p domain.Principal, repo domain.RepoName, ref AssetRef, offset, length int64, send func(AssetChunk) error) error
98	Usage(ctx context.Context, p domain.Principal, repo domain.RepoName) (ReleaseUsage, error)
99}
100
101// ReleaseTagWriter creates lightweight tags without moving existing refs.
102// *gitcli.Git implements it. An existing ref returns domain.ErrAlreadyExists.
103type ReleaseTagWriter interface {
104	CreateTag(ctx context.Context, repo domain.RepoName, tag string, target domain.ObjectID) error
105}
106
107// ReleaseTagTrigger handles tag deletion; *usecase.Releases implements it.
108type ReleaseTagTrigger interface {
109	OnRefsMoved(ctx context.Context, repo domain.RepoName, updates []domain.RefUpdate)
110}
111
112// ReleaseSweeper removes stale assets and blobs; *usecase.Releases implements it.
113type ReleaseSweeper interface{ Sweep(ctx context.Context) }
114
115// ReleaseRepoCleaner removes contents after metadata deletion; *usecase.Releases implements it.
116type ReleaseRepoCleaner interface {
117	AssetsOf(ctx context.Context, repo domain.RepoName) ([]domain.ReleaseAsset, error)
118	OnRepoDeleted(ctx context.Context, repo domain.RepoName, assets []domain.ReleaseAsset)
119}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 3

Tags 43

↑↓ moveenter openesc close