vshn / concierge-cli

Companion CLI for Concierge to bulk-manage repository projects.
https://pypi.org/project/concierge-cli/
BSD 3-Clause "New" or "Revised" License
8 stars 1 forks source link

Add `tag` command for bulk-tagging repositories #65

Open bittner opened 4 years ago

bittner commented 4 years ago

With our current release process we need to push a tag to all repositories we bulk-manage. On the GitLab Web frontend this is a bit time-consuming, and actually error-prone (you can easily overlook repositories).

On the command line we could easily do that quicker using just git, but we'd need to close every single repository. We should probably better do that via GitLab API calls.

Given that we'll release frequently and more in terms of "reflect the current state of are" (not in terms of release "features of a product") semver is likely less suitable as a versioning scheme than something that better reflects both a date/time "bandwidth" of release activities and blends in well in automated operations (e.g. increment last number when several releases need to be done). This might be a date-based scheme, e.g. YYYY.MM.c with c being a monthly release counter starting at 1 each month (or YY.MM.c like Ubuntu does it). EDIT: (see explanation below)

Needed Features

Examples

(See comment below)

bittner commented 4 years ago

As discussed in the backlog refinement, using semver will still make sense.

We should automate tagging by detecting the current common "latest tag" on a number of repositories, and increment the patch version component individually in an automatic fashion. Only repositories that have no Git tag set on the latest commit of the main branch should be considered as "need a Git tag to be set".

Overview (features)

$ concierge-cli tags --help
Usage: concierge-cli gitlab projects [OPTIONS] [GROUP_PROJECT_FILTER]

  List and manage Git tags on GitLab, optionally by topic.
  Strategy:
  1. calculate the 'major.minor' version common to all filtered repos
  2. increment the 'patch' version on each repository individually 

  Filter syntax:

  - foo/bar ... projects that have "bar" in their name, in groups that have
  "foo" in their name

  - foo/ ... filter for groups only, match any project

  - /bar ... filter for projects only, match any group

Options:
  --debug                       Show debug information on errors.
  --topic TEXT                  Use multiple times to filter with more
                                than one topic.
  --release [no|yes|automatic]  Create the Git version tag on the repos.
                                With "yes", will ask for confirmation
                                interactively on each MR.  [default: no]
  --bump [patch|minor|major]    Bump version component.  [default: patch]
  --help                        Show this message and exit.

List repositories

When listing the repositories, we loop over all the matching ones and calculate the common next version: (Note how one repository doesn't need updating; the latest commit already has a Git tag set, which is usually an error case and should rarely or never happen.)

$ concierge-cli tags mygroup/
🏷 Calculated common major.minor: v1.2
⚠ Warning: 1 projects would receive a major update, 1 projects a minor update.
mygroup/foo-project: v1.2.0 ➜ v1.2.1
mygroup/bar-project: (none) ➜ v1.2.0 ⚠
mygroup/baz-project: v1.2.3 βœ” (no change since last deployment) ⚠
mygroup/goo-project: v0.1.1 ➜ v1.2.0 ⚠
$ concierge-cli tags mygroup/ --bump minor
🏷 Calculated common major.minor: v1.2 ➜ v1.3
⚠ Warning: 2 projects would receive a major update.
mygroup/foo-project: v1.2.0 ➜ v1.3.0
mygroup/bar-project: (none) ➜ v1.3.0 ⚠
mygroup/baz-project: v1.2.3 βœ” (no change since last deployment) ⚠
mygroup/goo-project: v0.1.1 ➜ v1.3.0 ⚠
$ concierge-cli tags mygroup/ --bump major
🏷 Calculated common major.minor: v1.2 ➜ v2.0
⚠ Warning: 2 projects would skip intermediate version updates.
mygroup/foo-project: v1.2.0 ➜ v2.0.0
mygroup/bar-project: (none) ➜ v2.0.0 ⚠
mygroup/baz-project: v1.2.3 βœ” (no change since last deployment) ⚠
mygroup/goo-project: v0.1.1 ➜ v2.0.0 ⚠

Apply tags

Applying the proposed tags would work like this, interactive or automatic:

$ concierge-cli tags mygroup/ --bump minor --release yes
Push tag to mygroup/foo-project: v1.3.0 ? (y/n) [n] _
$ concierge-cli tags mygroup/ --release automatic
Pushing tag to mygroup/foo-project: v1.2.1
Pushing tag to mygroup/bar-project: v1.2.0
Pushing tag to mygroup/goo-project: v1.2.0