Proposal: Read release parameters from a JSON file
# Current solution
The `release-cli` currently supports taking all parameters to create a release using flags. These flags match exactly all the parameters defined in the [create a release](https://docs.gitlab.com/ee/api/releases/#create-a-release) section of the Releases API.
```shell
./bin/release-cli create -h
NAME:
help create - Create a Release using GitLab's Releases API https://docs.gitlab.com/ee/api/releases/#create-a-release
USAGE:
help create [command options] [arguments...]
OPTIONS:
--name value The release name
--description value The description of the release, you can use Markdown
--tag-name value The tag the release will be created from [$CI_COMMIT_TAG]
--ref value 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 [$CI_COMMIT_SHA]
--assets-links-name value [DEPRECATED use --assets-link instead] List of asset link names; must be used with --asset-links-url; ignored if --assets-link is defined (e.g. --assets-links-name "asset 1" --assets-links-url "https://example.com/url/1" --assets-links-name "asset 2" --assets-links-url "https://example.com/url/2")
--assets-links-url value [DEPRECATED use --assets-link instead] List of asset link URLs; must be used with --asset-links-name; ignored if --assets-link is defined (e.g. --assets-links-name "asset 1" --assets-links-url "https://example.com/url/1" --assets-links-name "asset 2" --assets-links-url "https://example.com/url/2")
--assets-link value JSON string representation of an asset link; takes precedence over --assets-links-name and --assets-links-url (e.g. --assets-link='{"name": "Asset1", "url":"https://<domain>/some/location/1", "type": "other", "filepath": "xzy" }'
--milestone value List of the titles of each milestone the release is associated with (e.g. --milestone "v1.0" --milestone "v1.0-rc)"; each milestone needs to exist
--released-at value The date when the release will be/was ready; defaults to the current time; expected in ISO 8601 format (2019-03-15T08:00:00Z)
--help, -h Show help (default: false)
```
## Problem to solve
Defining all these variables while running the `release-cli` becomes very verbose and it may be hard to follow, especially for flags that can be defined multiple times (e.g. `--assets-link` or `--milestone`).
Doing the validation of some of these flags is becoming more complex, as found in https://gitlab.com/gitlab-org/release-cli/-/issues/48#note_398524715 and https://gitlab.com/gitlab-org/release-cli/-/merge_requests/33#note_365724553.
It is hard to validate all the repeated flags when some parameters are required and some are not, for example, adding a direct asset link to a release. Name and URL are required, but `link_type` and `filepath` are not.
## Proposal
In #48 we decided to add an `--assets-link` flag that takes a JSON string that can define the correct relationship between the assets. This can be further extended to the `release-cli create` command to use a JSON file where all the parameters to create a release are defined in. For example,
```json
// cat release.json
{
"name": "release name",
"description": "release description",
"tag_name": "v1.1.0",
"ref": "2a4b8138a035174d0db1b2a0c4fb985edab7884d",
"milestones": ["m1", "m2"],
"released_at": "2020-06-30T07:00:00Z",
"assets": {
"links": [
{
"name": "asset 1",
"url": "https://example.com/asset/1",
"filepath": "/permanent/path",
"link_type": "other"
},
{
"name": "asset 2",
"url": "https://example.com/asset/2"
},
{
"name": "asset 3",
"url": "https://example.com/asset/3",
"link_type": "image"
}
]
}
}
```
Adding a `-file` flag to the `release-cli create` command to load the release from the file. This would look like
```shell
release-cli create -file release.json
```
### Advantages
1. Related assets parameters are defined together, reducing the relationship/validation concern found in https://gitlab.com/gitlab-org/release-cli/-/issues/48#note_398524715.
1. Parsing a JSON file would reduce the complexity from the `release-cli` logic to validate flags and generate the correct request for the Releases API.
1. Generating this file directly from the CI YAML `release` node would be straightforward on the Rails side (YAML->JSON conversion is a [well-known pattern](https://stackoverflow.com/questions/42226922/yaml-to-json-ruby)).
### Disadvantages
1. The caller of the `release-cli` needs to generate the `.json` file somehow. This is not a concern for GitLab CI (see point 3 above).
1. Moves the complexity out of the `release-cli`, giving the responsibility to standalone users.
### Questions
1. Should we support all the flags AND the `-file` option?
1. If we do, do we favor `-file` over individual flags?
1. Do we take the `-file` and other parameters together, overriding individual parameters. For example if `-name` and `-file` are passed together, do we load all the parameters from the file and only override `name`?
issue