Add release: publish tagged releases on the mirror servers
`release [@name ...] <tag> [notes]` does the whole chain in one step — create the annotated tag, push it to the internal server, then push it to each selected mirror and turn it into a release object there. Target selection reuses pushremote's @name mechanism, so the two behave alike. Notes are generated when none are given: the tag's own annotation when it carries more than the default, otherwise the commit subjects since the previous tag, capped at 50 lines. `tag add v1.0 "why this exists"` now takes a message, which is what that fallback reads; before, the annotation was always just the tag name. Tags ending in -rc/-alpha/-beta/-pre are marked as pre-releases on Gitea and GitHub. Releasing the same tag twice updates the existing release; a tag that already points at a different commit stops the command, since moving a published tag makes one version mean different things per server. A repository that is not on the mirror yet is reported instead of being created as a side effect. Binary assets are deliberately out of scope: Gitea attaches them to the release, GitHub uses a separate upload host, and GitLab does not host them at all but wants a link into its package registry. The providers differ in path shape and field names -- GitLab addresses projects by URL-encoded path, calls the notes "description" and has no pre-release flag -- so this comes with a recording httptest stand-in that asserts the exact requests for all three. That harness also covers authUser, repoExists and the auth header forms, which had no test at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,8 @@ directory. Go port of the original Perl `mgsh` (`mgsh.perl`).
|
||||
## Contents
|
||||
|
||||
- [Build](#build) · [Usage](#usage) · [Commands](#commands) · [Aliases](#aliases)
|
||||
- [Public mirror (`pushremote`)](#public-mirror-pushremote)
|
||||
- [Public mirror (`pushremote`)](#public-mirror-pushremote) ·
|
||||
[Releases](#releases)
|
||||
- [Configuration](#configuration) · [Settings reference](#settings-reference) ·
|
||||
[Per-project configuration](#per-project-configuration)
|
||||
- [Git server layout](#git-server-layout)
|
||||
@@ -38,9 +39,9 @@ stand in. Outside `base` no project is selected. `mgsh <project>` starts the
|
||||
interactive shell with that project preselected.
|
||||
|
||||
The commands available directly from the shell are `clone`, `init`, `log`,
|
||||
`push`, `pushremote`, `list`, `tag`, `archive`, `show`, `open`, `pull`, `fetch`,
|
||||
`status`, `diff`, `overview`, `config`, `count`, `login` and `cloneall`; every
|
||||
other command is interactive-only.
|
||||
`push`, `pushremote`, `release`, `list`, `tag`, `archive`, `show`, `open`,
|
||||
`pull`, `fetch`, `status`, `diff`, `overview`, `config`, `count`, `login` and
|
||||
`cloneall`; every other command is interactive-only.
|
||||
|
||||
The interactive prompt is colored (Catppuccin Mocha) and shows the active
|
||||
project, its git branch and a `*` dirty marker:
|
||||
@@ -87,7 +88,8 @@ Run `help` for the full list. Highlights:
|
||||
| `show <repo>` | show a repository log directly on the server |
|
||||
| `archive [comment]` | snapshot the server-side repo into `./archive` |
|
||||
| `init` | make a new repository from the current directory |
|
||||
| `tag [add/checkout/delete]` | manage tags |
|
||||
| `tag [add/checkout/delete]` | manage tags (`tag add v1.0 "why"` annotates) |
|
||||
| `release [@name] <tag> [notes]` | tag and publish a release on the mirrors |
|
||||
| `alias [name [cmd]]` | list, show or define a command alias |
|
||||
| `unalias <name>` | remove a command alias |
|
||||
| `config [-k]` | show the effective configuration and its sources |
|
||||
@@ -200,6 +202,46 @@ existing file is readable by others. The provider is auto-detected from `remoteu
|
||||
GitHub, `gitlab*` → GitLab, otherwise Gitea) and can be forced with
|
||||
`remotetype`. Set `mirror = true` to have every `push` mirror automatically.
|
||||
|
||||
### Releases
|
||||
|
||||
`release` turns a commit into a published release on the mirror servers, in one
|
||||
step — creating the tag, getting it onto the internal server, and then onto each
|
||||
mirror as a release object:
|
||||
|
||||
```
|
||||
release [@name ...] <tag> [notes]
|
||||
```
|
||||
|
||||
```
|
||||
< src/mgsh > release v4.1.0 first public build
|
||||
remote hub released https://github.com/mike/mgsh.git
|
||||
```
|
||||
|
||||
Without `@name` it releases to every configured mirror target, exactly like
|
||||
`pushremote`. Everything after the tag becomes the release notes *and* the tag's
|
||||
annotation.
|
||||
|
||||
**Notes are generated when you do not write any**: the tag's own annotation if
|
||||
it has a real one, otherwise the commit subjects since the previous tag
|
||||
(`- <subject>` per line, at most 50). So a plain `release v4.1.0` already
|
||||
produces a usable changelog.
|
||||
|
||||
A tag ending in `-rc`, `-alpha`, `-beta` or `-pre` (optionally with digits) is
|
||||
marked as a **pre-release** on Gitea and GitHub; GitLab has no such flag.
|
||||
|
||||
Releasing the same tag twice updates the existing release rather than failing.
|
||||
But a tag that already exists **on a different commit** stops the command —
|
||||
moving a published tag is how one version quietly comes to mean different things
|
||||
on different servers. `release` also refuses when the repository is not on the
|
||||
mirror yet and tells you to run `pushremote` first, rather than creating it as a
|
||||
side effect.
|
||||
|
||||
**No binary assets.** The three providers handle uploads in three incompatible
|
||||
ways — Gitea attaches them to the release, GitHub uses a separate upload host,
|
||||
and GitLab does not host them at all but expects a link into its package
|
||||
registry. mgsh publishes source releases with notes; if you need binaries,
|
||||
upload them with the provider's own tooling.
|
||||
|
||||
## Configuration
|
||||
|
||||
mgsh has **no built-in defaults**. Settings are resolved in three steps, each
|
||||
|
||||
Reference in New Issue
Block a user