diff --git a/changelogs/unreleased/docs-releases-api.yml b/changelogs/unreleased/docs-releases-api.yml new file mode 100644 index 00000000000..fba70c0006d --- /dev/null +++ b/changelogs/unreleased/docs-releases-api.yml @@ -0,0 +1,5 @@ +--- +title: Adds API documentation for releases +merge_request: 23901 +author: +type: added diff --git a/doc/api/releases.md b/doc/api/releases.md new file mode 100644 index 00000000000..bfd0cc1c4ea --- /dev/null +++ b/doc/api/releases.md @@ -0,0 +1,481 @@ +# Releases API + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/41766) in GitLab 11.7. +> - Using this API you can manipulate GitLab's [Release](../user/project/releases.md) entries. + +## List Releases + +Paginated list of Releases, sorted by `created_at`. + +``` +GET /projects/:id/releases +``` + +| Attribute | Type | Required | Description | +| ------------- | -------------- | -------- | --------------------------------------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). | + +Example request: + +```sh +curl --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "http://localhost:3000/api/v4/projects/24/releases" +``` + +Example response: + +```json +[ + { + "tag_name":"v0.2", + "description":"## CHANGELOG\r\n\r\n- Escape label and milestone titles to prevent XSS in GFM autocomplete. !2740\r\n- Prevent private snippets from being embeddable.\r\n- Add subresources removal to member destroy service.", + "name":"Awesome app v0.2 beta", + "description_html":"\u003ch2 dir=\"auto\"\u003e\n\u003ca id=\"user-content-changelog\" class=\"anchor\" href=\"#changelog\" aria-hidden=\"true\"\u003e\u003c/a\u003eCHANGELOG\u003c/h2\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eEscape label and milestone titles to prevent XSS in GFM autocomplete. !2740\u003c/li\u003e\n\u003cli\u003ePrevent private snippets from being embeddable.\u003c/li\u003e\n\u003cli\u003eAdd subresources removal to member destroy service.\u003c/li\u003e\n\u003c/ul\u003e", + "created_at":"2019-01-03T01:56:19.539Z", + "author":{ + "id":1, + "name":"Administrator", + "username":"root", + "state":"active", + "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", + "web_url":"http://localhost:3000/root" + }, + "commit":{ + "id":"079e90101242458910cccd35eab0e211dfc359c0", + "short_id":"079e9010", + "title":"Update README.md", + "created_at":"2019-01-03T01:55:38.000Z", + "parent_ids":[ + "f8d3d94cbd347e924aa7b715845e439d00e80ca4" + ], + "message":"Update README.md", + "author_name":"Administrator", + "author_email":"admin@example.com", + "authored_date":"2019-01-03T01:55:38.000Z", + "committer_name":"Administrator", + "committer_email":"admin@example.com", + "committed_date":"2019-01-03T01:55:38.000Z" + }, + "assets":{ + "count":6, + "sources":[ + { + "format":"zip", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.zip" + }, + { + "format":"tar.gz", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.tar.gz" + }, + { + "format":"tar.bz2", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.tar.bz2" + }, + { + "format":"tar", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.tar" + } + ], + "links":[ + { + "id":2, + "name":"awesome-v0.2.msi", + "url":"http://192.168.10.15:3000/msi", + "external":true + }, + { + "id":1, + "name":"awesome-v0.2.dmg", + "url":"http://192.168.10.15:3000", + "external":true + } + ] + } + }, + { + "tag_name":"v0.1", + "description":"## CHANGELOG\r\n\r\n-Remove limit of 100 when searching repository code. !8671\r\n- Show error message when attempting to reopen an MR and there is an open MR for the same branch. !16447 (Akos Gyimesi)\r\n- Fix a bug where internal email pattern wasn't respected. !22516", + "name":"Awesome app v0.1 alpha", + "description_html":"\u003ch2 dir=\"auto\"\u003e\n\u003ca id=\"user-content-changelog\" class=\"anchor\" href=\"#changelog\" aria-hidden=\"true\"\u003e\u003c/a\u003eCHANGELOG\u003c/h2\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eRemove limit of 100 when searching repository code. !8671\u003c/li\u003e\n\u003cli\u003eShow error message when attempting to reopen an MR and there is an open MR for the same branch. !16447 (Akos Gyimesi)\u003c/li\u003e\n\u003cli\u003eFix a bug where internal email pattern wasn't respected. !22516\u003c/li\u003e\n\u003c/ul\u003e", + "created_at":"2019-01-03T01:55:18.203Z", + "author":{ + "id":1, + "name":"Administrator", + "username":"root", + "state":"active", + "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", + "web_url":"http://localhost:3000/root" + }, + "commit":{ + "id":"f8d3d94cbd347e924aa7b715845e439d00e80ca4", + "short_id":"f8d3d94c", + "title":"Initial commit", + "created_at":"2019-01-03T01:53:28.000Z", + "parent_ids":[ + + ], + "message":"Initial commit", + "author_name":"Administrator", + "author_email":"admin@example.com", + "authored_date":"2019-01-03T01:53:28.000Z", + "committer_name":"Administrator", + "committer_email":"admin@example.com", + "committed_date":"2019-01-03T01:53:28.000Z" + }, + "assets":{ + "count":4, + "sources":[ + { + "format":"zip", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip" + }, + { + "format":"tar.gz", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz" + }, + { + "format":"tar.bz2", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2" + }, + { + "format":"tar", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar" + } + ], + "links":[ + + ] + } + } +] +``` + +## Get a Release by a tag name + +Get a Release for the given tag. + +``` +GET /projects/:id/releases/:tag_name +``` + +| Attribute | Type | Required | Description | +| ------------- | -------------- | -------- | --------------------------------------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). | +| `tag_name` | string | yes | The tag where the release will be created from. | + +Example request: + +```sh +curl --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "http://localhost:3000/api/v4/projects/24/releases/v0.1" +``` + +Example response: + +```json +{ + "tag_name":"v0.1", + "description":"## CHANGELOG\r\n\r\n- Remove limit of 100 when searching repository code. !8671\r\n- Show error message when attempting to reopen an MR and there is an open MR for the same branch. !16447 (Akos Gyimesi)\r\n- Fix a bug where internal email pattern wasn't respected. !22516", + "name":"Awesome app v0.1 alpha", + "description_html":"\u003ch2 dir=\"auto\"\u003e\n\u003ca id=\"user-content-changelog\" class=\"anchor\" href=\"#changelog\" aria-hidden=\"true\"\u003e\u003c/a\u003eCHANGELOG\u003c/h2\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eRemove limit of 100 when searching repository code. !8671\u003c/li\u003e\n\u003cli\u003eShow error message when attempting to reopen an MR and there is an open MR for the same branch. !16447 (Akos Gyimesi)\u003c/li\u003e\n\u003cli\u003eFix a bug where internal email pattern wasn't respected. !22516\u003c/li\u003e\n\u003c/ul\u003e", + "created_at":"2019-01-03T01:55:18.203Z", + "author":{ + "id":1, + "name":"Administrator", + "username":"root", + "state":"active", + "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", + "web_url":"http://localhost:3000/root" + }, + "commit":{ + "id":"f8d3d94cbd347e924aa7b715845e439d00e80ca4", + "short_id":"f8d3d94c", + "title":"Initial commit", + "created_at":"2019-01-03T01:53:28.000Z", + "parent_ids":[ + + ], + "message":"Initial commit", + "author_name":"Administrator", + "author_email":"admin@example.com", + "authored_date":"2019-01-03T01:53:28.000Z", + "committer_name":"Administrator", + "committer_email":"admin@example.com", + "committed_date":"2019-01-03T01:53:28.000Z" + }, + "assets":{ + "count":4, + "sources":[ + { + "format":"zip", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip" + }, + { + "format":"tar.gz", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz" + }, + { + "format":"tar.bz2", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2" + }, + { + "format":"tar", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar" + } + ], + "links":[ + + ] + } +} +``` + +## Create a release + +Create a Release. You need push access to the repository to create a Release. + +``` +POST /projects/:id/releases +``` + +| Attribute | Type | Required | Description | +| ------------- | -------------- | -------- | --------------------------------------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). | +| `name` | string | yes | The release name. | +| `tag_name` | string | yes | The tag where the release will be created from. | +| `description` | string | no | The description of the release. You can use [markdown](../user/markdown.md). | +| `ref` | string | no | If `tag_name` doesn't exist, the release will be created from `ref`. It can be a commit SHA, another tag name, or a branch name. | +| `assets:links`| array of hash | no | An array of assets links. | +| `assets:links:name`| string | no (if `assets:links` specified, it's required) | The name of the link. | +| `assets:links:url`| string | no (if `assets:links` specified, it's required) | The url of the link. | + +Example request: + +```sh +curl --header 'Content-Type: application/json' --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" \ + --data '{ "name": "New release", "tag_name": "v0.3", "description": "Super nice release", "assets": { "links": [{ "name": "hoge", "url": "https://google.com" }] } }' \ + --request POST http://localhost:3000/api/v4/projects/24/releases +``` + +Example response: + +```json +{ + "tag_name":"v0.3", + "description":"Super nice release", + "name":"New release", + "description_html":"\u003cp dir=\"auto\"\u003eSuper nice release\u003c/p\u003e", + "created_at":"2019-01-03T02:22:45.118Z", + "author":{ + "id":1, + "name":"Administrator", + "username":"root", + "state":"active", + "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", + "web_url":"http://localhost:3000/root" + }, + "commit":{ + "id":"079e90101242458910cccd35eab0e211dfc359c0", + "short_id":"079e9010", + "title":"Update README.md", + "created_at":"2019-01-03T01:55:38.000Z", + "parent_ids":[ + "f8d3d94cbd347e924aa7b715845e439d00e80ca4" + ], + "message":"Update README.md", + "author_name":"Administrator", + "author_email":"admin@example.com", + "authored_date":"2019-01-03T01:55:38.000Z", + "committer_name":"Administrator", + "committer_email":"admin@example.com", + "committed_date":"2019-01-03T01:55:38.000Z" + }, + "assets":{ + "count":5, + "sources":[ + { + "format":"zip", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.zip" + }, + { + "format":"tar.gz", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.tar.gz" + }, + { + "format":"tar.bz2", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.tar.bz2" + }, + { + "format":"tar", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.tar" + } + ], + "links":[ + { + "id":3, + "name":"hoge", + "url":"https://google.com", + "external":true + } + ] + } +} +``` + +## Update a release + +Update a Release. + +``` +PUT /projects/:id/releases/:tag_name +``` + +| Attribute | Type | Required | Description | +| ------------- | -------------- | -------- | --------------------------------------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). | +| `name` | string | no | The release name. | +| `tag_name` | string | no | The tag where the release will be created from. | +| `description` | string | no | The description of the release. You can use [markdown](../user/markdown.md). | + +Example request: + +```sh +curl --request PUT --data name="new name" --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "http://localhost:3000/api/v4/projects/24/releases/v0.1" +``` + +Example response: + +```json +{ + "tag_name":"v0.1", + "description":"## CHANGELOG\r\n\r\n- Remove limit of 100 when searching repository code. !8671\r\n- Show error message when attempting to reopen an MR and there is an open MR for the same branch. !16447 (Akos Gyimesi)\r\n- Fix a bug where internal email pattern wasn't respected. !22516", + "name":"new name", + "description_html":"\u003ch2 dir=\"auto\"\u003e\n\u003ca id=\"user-content-changelog\" class=\"anchor\" href=\"#changelog\" aria-hidden=\"true\"\u003e\u003c/a\u003eCHANGELOG\u003c/h2\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eRemove limit of 100 when searching repository code. !8671\u003c/li\u003e\n\u003cli\u003eShow error message when attempting to reopen an MR and there is an open MR for the same branch. !16447 (Akos Gyimesi)\u003c/li\u003e\n\u003cli\u003eFix a bug where internal email pattern wasn't respected. !22516\u003c/li\u003e\n\u003c/ul\u003e", + "created_at":"2019-01-03T01:55:18.203Z", + "author":{ + "id":1, + "name":"Administrator", + "username":"root", + "state":"active", + "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", + "web_url":"http://localhost:3000/root" + }, + "commit":{ + "id":"f8d3d94cbd347e924aa7b715845e439d00e80ca4", + "short_id":"f8d3d94c", + "title":"Initial commit", + "created_at":"2019-01-03T01:53:28.000Z", + "parent_ids":[ + + ], + "message":"Initial commit", + "author_name":"Administrator", + "author_email":"admin@example.com", + "authored_date":"2019-01-03T01:53:28.000Z", + "committer_name":"Administrator", + "committer_email":"admin@example.com", + "committed_date":"2019-01-03T01:53:28.000Z" + }, + "assets":{ + "count":4, + "sources":[ + { + "format":"zip", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip" + }, + { + "format":"tar.gz", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz" + }, + { + "format":"tar.bz2", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2" + }, + { + "format":"tar", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar" + } + ], + "links":[ + + ] + } +} +``` + +## Delete a Release + +Delete a Release. Deleting a Release will not delete the associated tag. + +``` +DELETE /projects/:id/releases/:tag_name +``` + +| Attribute | Type | Required | Description | +| ------------- | -------------- | -------- | --------------------------------------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). | +| `tag_name` | string | yes | The tag where the release will be created from. | + +Example request: + +```sh +curl --request DELETE --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "http://localhost:3000/api/v4/projects/24/releases/v0.1" +``` + +Example response: + +```json +{ + "tag_name":"v0.1", + "description":"## CHANGELOG\r\n\r\n- Remove limit of 100 when searching repository code. !8671\r\n- Show error message when attempting to reopen an MR and there is an open MR for the same branch. !16447 (Akos Gyimesi)\r\n- Fix a bug where internal email pattern wasn't respected. !22516", + "name":"new name", + "description_html":"\u003ch2 dir=\"auto\"\u003e\n\u003ca id=\"user-content-changelog\" class=\"anchor\" href=\"#changelog\" aria-hidden=\"true\"\u003e\u003c/a\u003eCHANGELOG\u003c/h2\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eRemove limit of 100 when searching repository code. !8671\u003c/li\u003e\n\u003cli\u003eShow error message when attempting to reopen an MR and there is an open MR for the same branch. !16447 (Akos Gyimesi)\u003c/li\u003e\n\u003cli\u003eFix a bug where internal email pattern wasn't respected. !22516\u003c/li\u003e\n\u003c/ul\u003e", + "created_at":"2019-01-03T01:55:18.203Z", + "author":{ + "id":1, + "name":"Administrator", + "username":"root", + "state":"active", + "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", + "web_url":"http://localhost:3000/root" + }, + "commit":{ + "id":"f8d3d94cbd347e924aa7b715845e439d00e80ca4", + "short_id":"f8d3d94c", + "title":"Initial commit", + "created_at":"2019-01-03T01:53:28.000Z", + "parent_ids":[ + + ], + "message":"Initial commit", + "author_name":"Administrator", + "author_email":"admin@example.com", + "authored_date":"2019-01-03T01:53:28.000Z", + "committer_name":"Administrator", + "committer_email":"admin@example.com", + "committed_date":"2019-01-03T01:53:28.000Z" + }, + "assets":{ + "count":4, + "sources":[ + { + "format":"zip", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip" + }, + { + "format":"tar.gz", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz" + }, + { + "format":"tar.bz2", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2" + }, + { + "format":"tar", + "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar" + } + ], + "links":[ + + ] + } +} +``` diff --git a/doc/user/project/img/releases.png b/doc/user/project/img/releases.png index aec1db89a75..f8b1b7305ad 100644 Binary files a/doc/user/project/img/releases.png and b/doc/user/project/img/releases.png differ diff --git a/doc/user/project/releases.md b/doc/user/project/releases.md index 8dad4240c91..3f3525829b8 100644 --- a/doc/user/project/releases.md +++ b/doc/user/project/releases.md @@ -2,11 +2,58 @@ > [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/41766) in GitLab 11.7. -Releases mark specific points in a project's development history, communicate -information about the type of change, and deliver on prepared, often compiled, -versions of the software to be reused elsewhere. Currently, releases can only be -created through the API. +It's typical to create a [Git tag](../../university/training/topics/tags.md) at +the moment of release to introduce a checkpoint in your source code +history, but in most cases your users will need compiled objects or other +assets output by your CI system to use them, not just the raw source +code. -Navigate to **Project > Releases** in order to see the list of releases of a project. +GitLab's **Releases** are a way to track deliverables in your project. Consider them +a snapshot in time of the source, build output, and other metadata or artifacts +associated with a released version of your code. + +At the moment, you can create Release entries via the [Releases API](../../api/releases.md); +we recommend doing this as one of the last steps in your CI/CD release pipeline. + +## Getting started with Releases + +Start by giving a [description](#release-description) to the Release and +including its [assets](#release-assets), as follows. + +### Release description + +Every Release has a description. You can add any text you like, but we recommend +including a changelog to describe the content of your release. This will allow +your users to quickly scan the differences between each one you publish. + +NOTE: **Note:** +[Git's tagging messages](https://git-scm.com/book/en/v2/Git-Basics-Tagging) and +Release descriptions are unrelated. Description supports [markdown](../markdown.md). + +### Release assets + +You can currently add the following types of assets to each Release: + +- [Source code](#source-code): state of the repo at the time of the Release +- [Links](#links): to content such as built binaries or documentation + +GitLab will support more asset types in the future, including objects such +as pre-built packages, compliance/security evidence, or container images. + +#### Source code + +GitLab automatically generate `zip`, `tar.gz`, `tar.bz2` and `tar` +archived source code from the given Git tag. These are read-only assets. + +#### Links + +A link is any URL which can point to whatever you like; documentation, built +binaries, or other related materials. These can be both internal or external +links from your GitLab instance. + +## Releases list + +Navigate to **Project > Releases** in order to see the list of releases for a given +project. ![Releases list](img/releases.png) diff --git a/doc/workflow/releases.md b/doc/workflow/releases.md index 6176784fc57..02388bb73ea 100644 --- a/doc/workflow/releases.md +++ b/doc/workflow/releases.md @@ -1,14 +1,16 @@ # Releases -You can turn any git tag into a release, by adding a note to it. -Release notes behave like any other markdown form in GitLab so you can write text and drag-n-drop files to it. -Release notes are stored in the database of GitLab. +NOTE: In GitLab 11.7, we introduced the full fledged [releases](../user/project/releases.md) feature. You can still create release notes on this page, but the new method is preferred. + +You can add release notes to any git tag using the notes feature. Release notes +behave like any other markdown form in GitLab so you can write text and +drag-n-drop files to it. Release notes are stored in GitLab's database. There are several ways to add release notes: -* In the interface, when you create a new git tag with GitLab +* In the interface, when you create a new git tag * In the interface, by adding a note to an existing git tag -* with the GitLab API +* Using the GitLab API ## New tag page with release notes text area