# Tags and releases

A tag and a release are one thing in Oak: an immutable name on a commit on `main`, with an optional title, notes, draft or prerelease mark, and downloadable assets. `oak tag` is the same command as `oak release`.

Releases are behind a per-repository server flag. Where it is off, the commands fail with the server's message. The flag is set by Oak server administrators, not by organization owners, and the CLI can't turn it on; ask us (see [Contributors](/docs/contributors)) if you need it. `oak pull` and `oak clone` copy the list of published tags and their assets into your checkout, but asset bytes are only downloaded by `oak release download`.

## Create

```bash
oak release create v1.2.0 dist/app.tar.gz --title "1.2.0" --notes-file NOTES.md
oak tag create checkpoint                       # main's head, no title or files
oak release create v1.1.9 --commit FULL_HASH --draft   # an older commit on main
```

The tag points at the head of `main` unless `--commit` names an older commit on `main`. Tags never move: creating a name that exists at a different commit fails, and you delete the tag first to reuse the name. Files after the name are uploaded as assets; only chunks the server lacks are sent. Flags: `-t, --title`, `-n, --notes`, `--notes-file` (`-` for stdin), `--draft`, `--prerelease`, `--finalize`.

## Read

```bash
oak release list [--limit N] [--offline] --json
oak release view v1.2.0 [--offline] --json
```

`--offline` reads the cache `oak pull` keeps instead of asking the server.

## Edit, publish, delete

```bash
oak release edit v1.2.0 --notes-file NOTES.md --expected-revision 3
oak release edit v1.1.9 --publish      # publish a draft (one way)
oak release edit v1.2.0 --finalize     # freeze the asset list (one way)
oak release delete v1.2.0 --yes
```

A tag's commit never changes. `--expected-revision N` refuses the edit unless the tag is still at that revision. Drafts are visible only to people who can write, and aren't synced by `oak pull`.

## Assets

```bash
oak release upload v1.2.0 extra.zip [--as NAME]
oak release download v1.2.0 [ASSET...] -d out/ [--force]
oak release remove-asset v1.2.0 extra.zip     # only before the tag is finalized
```

`download` checks each file against its content hash before writing it, and won't overwrite a different file without `--force`.

## Tags from a Git import

`oak clone <git-url>` keeps the Git repository's tags locally. After you push the commits they point at, `oak release push` publishes those tags to the server. Their commits must already be on `main`.

See the [CLI reference](/docs/cli#oak-release-oak-tag) for every flag.
