Automatically tag and release secure analyzers
### Problem to solve While working on [Build docker images on a regular schedule](https://gitlab.com/gitlab-org/gitlab/-/issues/338826), there was a [discussion](https://gitlab.com/gitlab-org/security-products/ci-templates/-/merge_requests/255#note_702235232) about whether we should fetch the most recent version of the analyzer from the `git tag` or from the `CHANGELOG.md` file. A concern was raised that if a developer forgets to tag and release an analyzer, the most recent version in the `CHANGELOG.md` file would not match the most recent `git tag`, since a tag wasn't created. It was decided that we could address this issue, but it was out of scope, so that's why this new issue is being created to track it. ### Proposal The scheduled job for automatically building Docker images (see [gemnasium](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/pipeline_schedules), [retire.js](https://gitlab.com/gitlab-org/security-products/analyzers/retire.js/-/pipeline_schedules), [bundler-audit](https://gitlab.com/gitlab-org/security-products/analyzers/bundler-audit/-/pipeline_schedules), etc) currently does the following: 1. [Fetches the most recent version of the analyzer using `git tag -l`](https://gitlab.com/gitlab-org/security-products/ci-templates/-/blob/4ee6b59baafa3666753836a75e51f279a6d42dca/includes-dev/docker.yml#L72) 1. Rebuilds the analyzer with the version value fetched in step `1.` We should update this process to the following: 1. Fetch the most recent version of the analyzer and the description of the change from the `CHANGELOG.md` file. 1. Check to see if a tag already exists with the given version value fetched in step `1.`: - If such a tag exists, then rebuild a new analyzer Docker image with that tag - If a tag does not exist, tag a new analyzer Docker image with that tag and provide a tag description which matches the description for the change from the `CHANGELOG.md` file ### Implementation Plan Create an MR with the following changes, and notify the Static Analysis team about the new `CREATE_GIT_TAG` variable in case they also want to make use of it: 1. Create a new stage: `tag` (this contains a job for creating the git tag from the most recent changelog entry if it doesn't exist) 1. Create a new job `upsert git tag` in the `tag` stage. Use the code in [this commit](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/90a7045d2eafc3ddf0a462ca2b94795d83096c47/.gitlab-ci.yml) as a starting point. This job is idempotent and will: 1. Add a new CI variable `CREATE_GIT_TAG` (create a git tag if missing) 1. Fetch the most recent version of the analyzer and the description of the change from the `CHANGELOG.md` file. 1. If a git tag matching the version from the `CHANGELOG.md` file does not exist, create a new git tag, provide a tag description which matches the description for the change from the `CHANGELOG.md` file Note: The job is skipped unless `CREATE_GIT_TAG` is true 1. Update the `CI/CD Environment variables` following projects to set `CREATE_GIT_TAG: true` and also configure the `GITLAB_TOKEN` environment variable to match the one in the [ci-templates](https://gitlab.com/gitlab-org/security-products/ci-templates/-/settings/ci_cd) `CI/CD Settings`: - [gemnasium](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium) - [gemnasium-maven](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven) - [gemnasium-python](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-python) - [retire.js](https://gitlab.com/gitlab-org/security-products/analyzers/retire.js) - [bundler-audit](https://gitlab.com/gitlab-org/security-products/analyzers/bundler-audit) ### Future Steps 1. Increase the frequency of the scheduled CI piplines. 1. Create a new MR with the following changes, and include the Static Analysis team to make sure they approve the changes: 1. Rename [`release-major`](https://gitlab.com/gitlab-org/security-products/ci-templates/blob/4ee6b59/includes-dev/docker.yml#L7-7) stage to `release` 1. Rename [`major`](https://gitlab.com/gitlab-org/security-products/ci-templates/blob/4ee6b59/includes-dev/docker.yml#L106-112) to `release major` 1. Rename [`minor`](https://gitlab.com/gitlab-org/security-products/ci-templates/blob/4ee6b59/includes-dev/docker.yml#L113-118) to `release minor` 1. Rename [`tag version`](https://gitlab.com/gitlab-org/security-products/ci-templates/blob/4ee6b59/includes-dev/docker.yml#L87-97) to `release patch` 1. Merge [`release-version`](https://gitlab.com/gitlab-org/security-products/ci-templates/blob/4ee6b59/includes-dev/docker.yml#L6-6) into `release` See [this MR](https://gitlab.com/gitlab-org/security-products/ci-templates/-/merge_requests/270) for a starting point for the above changes. 1. Export the `major`, `minor`, `patch` version numbers as CI variables to be used by the `release` jobs using [dotenv export artifact](https://docs.gitlab.com/ee/ci/variables/#pass-an-environment-variable-to-another-job) 1. If things go well and Static Analysis agrees with the change, remove the `PUBLISH_IMAGES` and `CREATE_GIT_TAG` variables. By removing these variables, the behaviour of the default branch build will be to automatically create a new git tag if one doesn't exist, and release the images ### Intended users * [Sasha (Software Developer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#sasha-software-developer) ### Further details This change will eliminate the need for this issue: [Warn when analyzer changelog is updated without a new release](https://gitlab.com/gitlab-org/gitlab/-/issues/338858) ### Documentation - Update the [Versioning and release process](https://gitlab.com/gitlab-org/security-products/analyzers/common#versioning-and-release-process) docs - ~~Update the [Security and Build fixes of Go](https://about.gitlab.com/handbook/engineering/development/secure/release_process.html#git-tag-to-rebuild) docs~~ (not necessary - see [this discussion](https://gitlab.com/gitlab-org/gitlab/-/issues/342986#note_812309162) for more details) ### What does success look like, and how can we measure that? If a developer forgets to release an analyzer, it will automatically be built and released from a scheduled job. We can test this by updating the changelog entry for an analyzer and ensuring that the scheduled job automatically tags and releases a new version. ### What is the type of buyer? ~"Enterprise Applications" ~"GitLab Ultimate" ### Is this a cross-stage feature? This change will affect ~"Category:Dependency Scanning". If ~"Category:SAST" wants to make use of it, they can do so by setting `CREATE_GIT_TAG: "true"` and configuring `GITLAB_TOKEN` to a valid access token. /cc @NicoleSchwartz @gonzoyumo @fcatteau
issue