Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 94 additions & 11 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,110 @@ jobs:
github_app: grafana-otel-bot
permission_set: default

- name: Get version
- name: Determine next version
id: get-version
shell: pwsh
env:
GH_TOKEN: ${{ steps.get-token.outputs.token }}
NEXT_VERSION: ${{ inputs.version }}
run: |
if (-Not [string]::IsNullOrEmpty(${env:NEXT_VERSION})) {
$nextVersion = [System.Version]::new(${env:NEXT_VERSION}.TrimStart('v'))
} else {
$latestUrl = "${env:GITHUB_API_URL}/repos/${env:GITHUB_REPOSITORY}/releases/latest"
$headers = @{
Authorization = "Bearer ${env:GH_TOKEN}";
Accept = "application/vnd.github+json";
# Get the component versions from the container image environment variables
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this logic is quite involved - would it make sense to extract it to a script that can be tested?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered adding it to a script, but then the only difference is that the repo now needs to be cloned to get it.

In terms of testability, you can just copy the script into a pwsh terminal and run it directly after setting a few env vars (which is how I tested it before opening the PR):

# <paste script excluding final two lines

Which outputs the following for different input combinations:

> ${env:NEXT_VERSION}=""
> ${env:GITHUB_REPOSITORY}="grafana/docker-otel-lgtm"
> Get-Next-LGTM-Version ${env:NEXT_VERSION}
0.11.19

> ${env:NEXT_VERSION}="0.12.0"
> Get-Next-LGTM-Version ${env:NEXT_VERSION}
0.12.0

> ${env:NEXT_VERSION}="v0.12.0"
> Get-Next-LGTM-Version ${env:NEXT_VERSION}
0.12.0

> Get-Component-Versions "ghcr.io/grafana/docker-otel-lgtm:main"

Name                           Value
----                           -----
GRAFANA                        12.3.0
LOKI                           3.6.2
OPENTELEMETRY_COLLECTOR        0.139.0
PROMETHEUS                     3.7.3
PYROSCOPE                      1.16.0
TEMPO                          2.9.0

> Get-Component-Versions "grafana/otel-lgtm:latest"

Name                           Value
----                           -----
GRAFANA                        12.3.0
LOKI                           3.6.1
OPENTELEMETRY_COLLECTOR        0.139.0
PROMETHEUS                     3.7.3
PYROSCOPE                      1.16.0
TEMPO                          2.9.0

> Get-Component-Versions "grafana/otel-lgtm:0.11.16"

Name                           Value
----                           -----
GRAFANA                        12.2.1
LOKI                           3.5.7
OPENTELEMETRY_COLLECTOR        0.139.0
PROMETHEUS                     3.7.3
PYROSCOPE                      1.15.0
TEMPO                          2.9.0

I'll refactor slightly so that the increment can be easily tested separately.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the latest refactor and we pretend that the last release was 0.11.10:

> ${env:NEXT_VERSION}=""
> $currentVersion = [System.Version]::new("0.11.10")
> $next = Get-Component-Versions "ghcr.io/grafana/docker-otel-lgtm:main"
> $current = Get-Component-Versions "grafana/otel-lgtm:0.11.10"
> Get-Next-Version $currentVersion $current $next
0.12.0

function Get-Component-Versions {
param([string]$Image)

docker pull $Image 2>&1 | Out-Null
$vars = docker image inspect --format '{{json .Config.Env}}' $Image | ConvertFrom-Json

$result = [ordered]@{}
$suffix = "_VERSION"

foreach ($var in $vars | Sort-Object) {
$parts = $var -split '=', 2

$key = $parts[0]
$value = $parts[1]

if ($key.EndsWith($suffix)) {
$result[$key.Substring(0, $key.Length - $suffix.Length)] = [System.Version]::new($value.TrimStart("v"))
}
}

$result
}

function Get-Next-Version {
param(
[System.Version]$Version,
[hashtable]$Current,
[hashtable]$Next
)

# Determine if any components have major or minor version changes
$major = $false
$minor = $false

foreach ($key in $Current.Keys) {
if ($null -eq $Next[$key]) {
# If we remove a component, consider it a major change
$major = $true
continue
}

if ($null -eq $Current[$key]) {
# If we add a component, consider it a major change
$major = $true
continue
}

$currentComponent = $Current[$key]
$nextComponent = $Next[$key]

if ($nextComponent.Major -gt $currentComponent.Major) {
$major = $true
break
}

if ($nextComponent.Minor -gt $currentComponent.Minor) {
$minor = $true
}
}

# For major or minor changes, bump the minor version and reset the patch version.
# For any other changes, just bump the patch version.
if ($major -or $minor) {
$nextVersion = [System.Version]::new($Version.Major, $Version.Minor + 1, 0)
}
else {
$nextVersion = [System.Version]::new($Version.Major, $Version.Minor, $Version.Build + 1)
}

$nextVersion.ToString()
}

function Get-Next-LGTM-Version {

param([string]$NextVersion)

# Use the version as provided
if (-Not [string]::IsNullOrEmpty($NextVersion)) {
[System.Version]::new($NextVersion.TrimStart('v')).ToString()
return
}
$latest = (Invoke-RestMethod -Uri $latestUrl -Headers $headers -ErrorAction Stop).tag_name.TrimStart('v')

# Get the versions of the components in the latest release and the main branch
$current = Get-Component-Versions "docker.io/grafana/otel-lgtm:latest"
$next = Get-Component-Versions "ghcr.io/grafana/docker-otel-lgtm:main"

# Get the current release version from the latest GitHub release
$latest = (gh api "/repos/${env:GITHUB_REPOSITORY}/releases/latest" --jq .tag_name).TrimStart('v')
$currentVersion = [System.Version]::new($latest)
$nextVersion = [System.Version]::new($currentVersion.Major, $currentVersion.Minor, $currentVersion.Build + 1)

$nextVersion = Get-Next-Version $currentVersion $current $next

$nextVersion.ToString()
}

$releaseVersion = $nextVersion.ToString()
$releaseVersion = Get-Next-LGTM-Version ${env:NEXT_VERSION}
"version=${releaseVersion}" >> ${env:GITHUB_OUTPUT}

- name: Create release
Expand Down
48 changes: 48 additions & 0 deletions .github/workflows/scheduled-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
name: Scheduled Release

on:
#schedule:
# - cron: '0 9 * * FRI'
workflow_dispatch:

permissions: {}

jobs:
release:
runs-on: ubuntu-24.04
timeout-minutes: 10

permissions:
actions: write

steps:
- name: Checkout repository
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
with:
fetch-depth: 0
persist-credentials: false

- name: Get changes since last release
id: get-changes
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
LATEST="$(gh api "/repos/${GITHUB_REPOSITORY}/releases/latest" --jq .tag_name)"
CHANGED_FILES="$(git diff --name-only "${LATEST}" -- docker || true)"
if [ -n "${CHANGED_FILES}" ]; then
echo "docker/ has changes since ${LATEST}"
echo "has-changes=true" >> "${GITHUB_OUTPUT}"
else
echo "docker/ has no changes since ${LATEST}"
echo "has-changes=false" >> "${GITHUB_OUTPUT}"
fi
- name: Publish release
if: steps.get-changes.outputs.has-changes == 'true'
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh workflow run publish-release.yml --field draft=true