stackver
is a tool to help track the versions of your stack dependencies. As systems become more microservice oriented, it is critical to stay on top of your version dependencies to ensure you are not running into any security vulnerabilities or functional regressions. While a CMDB is good at tracking the historic versions of your stack, it is often difficult to relate these to their current upstream versions.
stackver
is a tool to help you do just that. It will take a list of your stack dependencies and utilize predefined upstream trackers
to find any new releases. It will then compare these new releases to your current stack and output a report of any new releases, as well as notify you of if/when your current versions go EOL. This gives your technical teams visibility to and lead time on any upcoming changes to your stack, so they can be adequately integration tested in test environments before being deployed to production.
stackver
is configured with a YAML (or JSON) manifest. This manifest should contain all of the dependencies in this stack, and their current versions. For example:
---
metadata:
name: stack
spec:
dependencies:
- name: kubernetes
version: 1.27.3
- name: istio
version: 1.19.3
- name: cert-manager
version: 1.13.1
tracker:
kind: github
uri: cert-manager/cert-manager
- name: cert-manager-sync
version: a22c122
tracker:
kind: github
uri: robertlestak/cert-manager-sync
This contains the metadata for the manifest itself. Currently, the only required field is name
, which is used to identify the manifest in the output. This is useful if you are tracking multiple stacks.
This contains the actual dependencies in your stack under the dependencies
key. Each dependency should be defined by its name
and version
. The name
is used to identify the dependency in the output, and the version
is the current version of the dependency in your stack. This is the version that will be compared against the latest upstream version.
The version
field is required and should be the current version of the dependency in your stack. This is the version that will be compared against the latest upstream version.
The tracker
field is optional and should be used to define the upstream tracker for this dependency. If no tracker is defined, stackver
will use the endoflife
tracker by default. See the Trackers section for more information.
If no tracker.uri
is provided, the dependency key name is used.
stackver
uses trackers
to find new releases of your dependencies. A tracker is a simple Go interface that implements a GetStatus
method. This method should retrieve the latest release details from the defined upstream, compare those against the currrent version, and return a ServiceStatus
object. The following trackers are currently implemented:
The endoflife
tracker uses the endoflife.date API to track the EOL status of your dependencies. endoflife.date is an awesome community-driven project that tracks the EOL status of many popular open source projects. If no tracker is defined, this will be used as the default.
endoflife
returns a full EOL date, enabling stackver
to notify you of upcoming EOLs relative to the current date. This is the ideal tracker to use for most dependencies.
The github
tracker uses the GitHub API to track the latest releases of your dependencies. It will first try to find the version by the /releases
API. If a release with the defined version is not found, it will fallback to searching by the commit hash in the /commits
API.
Since github
will only return the release itself and not meta information such as support cycles or EOL dates, stackver
will not be able to notify you of upcoming EOLs. Instead, it will simply be able to notify you of new releases, so you will at least know when a new version is available.
Note: The GitHub API uses aggressive rate limits, so you'll probably want to set the GITHUB_TOKEN
environment variable to a personal access token. This will increase your rate limit from 60 requests per hour to 5000 requests per hour.
When run, stackver
evaulates the provided stack manifest and outputs a report of the current status of each dependency. The following output formats are currently supported:
The text
output format is the default output format. It will output a simple text report of the current status of each dependency. For example:
Name Version Latest EOL Date Status Link
kubernetes 1.27.3 1.28.3 2024-06-28 good https://endoflife.date/kubernetes
istio 1.19.3 1.19.3 2024-03-31 current https://endoflife.date/istio
cert-manager 1.13.1 1.13.2 unknown good https://github.com/cert-manager/cert-manager/releases
cert-manager-sync a22c122 a22c122 unknown current https://github.com/robertlestak/cert-manager-sync
The csv
output format will output a simple CSV report of the current status of each dependency. For example:
Name,Version,Latest,EOL Date,Status,Link
kubernetes,1.27.3,1.28.3,2024-06-28,good,https://endoflife.date/kubernetes
istio,1.19.3,1.19.3,2024-03-31,current,https://endoflife.date/istio
cert-manager,1.13.1,1.13.2,unknown,good
cert-manager-sync,a22c122,a22c122,unknown,current
This is useful for importing into other tools such as spreadsheets. GitHub UI also supports rendering CSV files, so you can simply commit the CSV reports to your repository and view them in the GitHub UI.
The yaml
output format will output a more detailed YAML report of the current status of each dependency. For example:
---
metadata:
name: stack
spec:
dependencies:
- name: kubernetes
version: 1.27.3
tracker:
kind: endoflife
uri: kubernetes
status:
latestVersion: 1.28.3
currentVersionEOLDate: 2024-06-28T00:00:00Z
link: https://endoflife.date/kubernetes
status: good
- name: istio
version: 1.19.3
tracker:
kind: endoflife
uri: istio
status:
latestVersion: 1.19.3
currentVersionEOLDate: 2024-03-31T00:00:00Z
link: https://endoflife.date/istio
status: current
- name: cert-manager
version: 1.13.1
tracker:
kind: github
uri: cert-manager/cert-manager
status:
latestVersion: 1.13.2
link: https://github.com/cert-manager/cert-manager/releases
status: good
- name: cert-manager-sync
version: a22c122
tracker:
kind: github
uri: robertlestak/cert-manager-sync
status:
latestVersion: a22c122
link: https://github.com/robertlestak/cert-manager-sync
status: current
The json
output format will output a more detailed JSON report of the current status of each dependency, similar to YAML.
The prometheus
output format will output a Prometheus Gauge metric which can be used to track the status of your stack dependencies over time.
Status strings are converted to integers as follows (tl;dr lower is better):
current
=0
good
=1
update-available
=2
warning
=3
danger
=4
critical
=5
For example:
# HELP stackver_service_status Stackver service status
# TYPE stackver_service_status gauge
stackver_service_status{eol_date="2024-03-31",latest="1.19.3",link="https://endoflife.date/istio",name="istio",status="current",version="1.19.3"} 0
stackver_service_status{eol_date="2024-06-28",latest="1.28.3",link="https://endoflife.date/kubernetes",name="kubernetes",status="good",version="1.27.3"} 1
stackver_service_status{eol_date="unknown",latest="1.13.2",link="https://github.com/cert-manager/cert-manager/releases",name="cert-manager",status="good",version="1.13.1"} 1
stackver_service_status{eol_date="unknown",latest="a22c122",link="https://github.com/robertlestak/cert-manager-sync",name="cert-manager-sync",status="current",version="a22c122"} 0
Usage of stackver:
-d int
days until danger (default 30)
-f string
stack file
-o string
output format (default "text")
-v print version
-w int
days until warning (default 60)
stackver
writes its output to stdout
, so you can pipe it to a file or another program. For example:
$ stackver -f stack.yaml -o yaml > stack.yaml
If -f
is a directory, stackver
will search for all .yaml
and .json
files and evaluate them all. When in directory mode, if an argument is passed, it will be used as the output directory. For example:
$ stackver -f stack -o yaml stack-reports
stackver
is also available as a Docker image. You can run it as follows:
$ docker run --rm -v $(pwd):/stack robertlestak/stackver -f stack.yaml -o yaml > stack.yaml
The default working directory is /stack
, so if you mount your stack manifests to this directory you can reference them with their relative paths as above. Otherwise you'll need to use the full path to the manifest, e.g. -f /custom-mount/stack.yaml
.
stackver
is designed to be run as part of an automated pipeline to periodicially check your dependencies and alert you of any upcoming EOL dates / new releases. stackver
itself is solely responsible for generating the reports, and expects you to rely on pre-existing workflow and alerting systems.
For example, you could run it as a GitHub Action on a schedule to track the versions of your stack dependencies over time and commit the reports to your repository. This would allow you to track the versions of your stack dependencies over time, as well as provide a historical record of the status of your stack.
You could also use the prometheus
output format and node_exporter
to track the status of your stack dependencies over time in a Prometheus/Grafana dashboard, and alert you with Grafana's native alerting system.
stackver
is published as a GitHub Action which you can use in your existing workflows. For example:
name: stackver
on:
# check on every push to main branch
push:
branches:
- main
# only check stack manifest changes
paths:
- 'stack-manifests/**'
# check every day at midnight
schedule:
- cron: '0 0 * * *'
jobs:
stackver:
# this must be run on a linux machine
runs-on: ubuntu-latest
# let stackver access the repository
permissions:
contents: write
steps:
# checkout manifests
- uses: actions/checkout@v4
# run stackver and commit the reports to the repository
- uses: robertlestak/stackver@main
with:
stack: stack-manifests
output: reports/stack-manifests
githubToken: ${{ secrets.GITHUB_TOKEN }}
This will run stackver
on a schedule and commit the reports to the reports/stack-manifests
directory in your repository. You can then use this to track the versions of your stack dependencies over time, as well as provide a historical record of the status of your stack.
Note that you must checkout your repository before running stackver
so it can access your stack manifests. You must also provide a githubToken
so stackver
can access the GitHub API if you want to use the github
tracker and/or push the reports back to your repository.
Name | Description | Required | Default |
---|---|---|---|
stack |
The path to your stack manifests. This can be a single file or a directory. If a directory is provided, stackver will search for all .yaml and .json files and evaluate them all. |
true |
N/A |
output |
The path to write the reports to. If a directory is provided, stackver will write the reports to the provided directory with the same name as the manifest. If a file is provided, stackver will write the reports to the provided file. |
false |
stdout |
githubToken |
A GitHub personal access token to use to access the GitHub API. This is required if you want to use the github tracker and/or push the reports back to your repository. |
false |
N/A |
daysUntilWarning |
The number of days until a warning should be generated. | false |
60 |
daysUntilDanger |
The number of days until a danger should be generated. | false |
30 |
format |
The output format to use. | false |
csv |
stackVerVersion |
The version of stackver to use. |
false |
latest |
commit |
Whether or not to commit the reports back to the repository. | false |
true |
commitMessage |
The commit message to use. | false |
Update stack versions |
commitBranch |
The branch to commit the reports to. | false |
main |