Improve workflow to release Secure analyzers for a patch version of Go
Problem to solve
As a project maintainer of Secure analyzers implemented in Go, I need to quickly release new versions of the analyzers I maintain when a patch release is available for Go.
As a developer contributing to these projects, I need to know what version of Go was used to build a given Docker image of given analyzer.
Intended users
This is intended to project maintainers of the devopssecure analyzer projects implemented in Go, that is groupcomposition analysis and groupstatic analysis. The solution can also be adopted by devopsprotect, to ease the maintenance of Category:Container Scanning.
Proposal
The proposal can be summarized by 3 key points:
- change the
Dockerfile
to track the minor version of Go - use BUILD tag to release a new Docker image that comes with a patch version of Go
- don't specify the patch version of Go in the codebase or in the changelog
- report the exact version of Go in the log of the build log
When aware of new patch version of Go, project maintainers check the analyzer projects to see if it needs to be re-built and re-published (or they might simply skip that). If this is the case, they create a new git tag with the same MAJOR.MINOR.PATCH
version, but a different +BUILD
tag. For instance, if the last git tag is v3.4.5
, they create a new git tag v3.4.5-1
. This will trigger a new build, and publish the image as 3.4.5-1
and 3
.
The exact version of Go isn't in the project CHANGELOG because it wouldn't be accurate, because a new patch version of Go can be released at any time.
Creating a new git tag with a different BUILD metadata truly reflects what happens: the Docker image is re-built. Also, this is consistent with the CHANGELOG (no new changelog entry), and has the side-effect of triggering a full pipeline that pushes the images used in production, which is needed.
Analyzer projects might accidentally upgrade to a new patch version of Go when pushing new features or bug fixes. This is intended, as we assume that latest patch versions of Go are 100% backward compatible. If that's not the case then QA will fail, which is OK.
The Docker build argument GO_VERSION
can remain because it provides an easy way to try out specific versions of Go. This is useful when checking compatibility with a new MINOR version, or when we have to rollback the implicit upgrade and figure out what was the last compatible PATCH version.
The GO_VERSION
is removed from the shared CI template, and gitlab-org/security-products/ci-templates!135 (merged) is reverted.
The upgrade to a new MINOR version of Go has to be handled manually or using scripts that bulk update all the analyzer project. In the future, we might create a CI job that automatically creates MRs to do that, similar to the update_analyzers
job of the common library.
Pros:
- releasing a new version of the analyzer for a patch version of is really easy, and it takes very little time
- active analyzer projects automatically upgrade to new patch versions of Go, as MRs get merged
- the code tells what minor version of Go is used
- the Dockerfile truly reflects the build of the official Docker image
Cons:
- the code doesn't directly say what patch version of Go was used at a particular time, though it's possible to jump from the git tag to the pipeline, and find the information in the
log
of the build job
Implementation plan
-
make sure all devopssecure analyzer projects using Go are aligned with this, and that they use Go 1.15 in their multi-stage Dockerfiles -
update the Secure Release Process documentation, and repeat the key points of the proposal; this my be ported to the Protect section of the handbook gitlab-com/www-gitlab-com!71760 (merged) -
update the Dockerfiles of analyzer projects so that version of Go shows up when building the binary; ideally, we'll figure out a way to do that without repeating the same change in all projectscovered by #292228 (closed)
Permissions and Security
No change.
Documentation
To be documented in the Secure Release Process:
- applies to all devopssecure analyzers implemented in Go
- multi-stage Dockerfile tracks a major version of Go (i.e. 1.15)
- CHANGELOG doesn't mention the minor revision of Go (i.e. 1.15.4)
- project is upgraded implicitly to the latest minor revision
- backward compatibility with earlier minor revisions is assumed
- if upgrade is needed but there's nothing to release, maintainers create a git tag that matches the last version of the CHANGELOG, but with a different build metadata; see SemVer; a new version of the analyzer is released
Availability & Testing
This wouldn't be covered by QA but could be tested on a clone of an official analyzers project.
What does success look like, and how can we measure that?
Project maintainers of the Secure analyzers implemented in Go can quickly publish and deploy a patch release for the analyzers as soon as they're aware of a patch release of Go.
Developers contributing to these projects can easily figure out what version of Go what used to build a particular image of the Secure analyzers.
What is the type of buyer?
N/A
Is this a cross-stage feature?
Yes. This is primarily for devopssecure but it's applicable to devopsprotect.