Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
90 changes: 90 additions & 0 deletions .github/workflows/promote-release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: promote-release
run-name: '${{ github.event.release.tag_name }} release'

# Chart publish is gated on promotion (marked latest), not release-cut, so a
# pre-release image can be trialed via image.tag override first.
on:
release:
types: [released]

permissions:
contents: read

jobs:
check-promotion:
name: check-promotion
runs-on: ubuntu-latest
outputs:
skip: ${{ steps.check.outputs.skip }}
steps:
- name: "[validation] check this release is github's current latest"
id: check
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
tag="${{ github.event.release.tag_name }}"

# Only act on version-shaped tags.
if [[ ! "$tag" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+ ]]; then
echo "::notice::$tag doesn't look like a release version — skipping chart publish."
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi

# Skip if this promotion isn't GitHub's current latest release, so
# the chart's default appVersion can't move backwards. `gh release
# view` has no isLatest field — the /releases/latest endpoint is
# the actual source of truth for what GitHub considers latest.
latest_tag=$(gh api "repos/${{ github.repository }}/releases/latest" --jq '.tag_name')
if [ "$latest_tag" != "$tag" ]; then
echo "::notice::$tag was promoted but is not GitHub's current latest release ($latest_tag is) — skipping chart publish."
echo "skip=true" >> "$GITHUB_OUTPUT"
fi

publish-chart:
name: publish-chart
runs-on: ubuntu-latest
needs: [check-promotion]
if: needs.check-promotion.outputs.skip != 'true'
permissions:
contents: read
packages: write
steps:
- name: '[preparation] checkout the release tag'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event.release.tag_name }}

- name: '[preparation] resolve version'
id: version
run: |
tag="${{ github.event.release.tag_name }}"
echo "value=${tag#v}" >> "$GITHUB_OUTPUT"

- name: '[preparation] set up docker buildx'
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0

# Public repo, so this reads anonymously.
- name: '[validation] verify referenced image exists'
run: |
image="portainer/portainer-run:${{ steps.version.outputs.value }}"
if ! docker buildx imagetools inspect "$image" >/dev/null 2>&1; then
echo "::error::$image does not exist on Docker Hub — refusing to publish a chart that references a missing image."
exit 1
fi

- name: '[preparation] set up helm'
uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # v5.0.1

- name: '[preparation] log in to ghcr'
run: echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin

- name: '[execution] package chart'
run: |
helm package chart/ \
--version "${{ steps.version.outputs.value }}" \
--app-version "${{ steps.version.outputs.value }}" \
-d /tmp/chart-dist

- name: '[execution] push chart'
run: helm push /tmp/chart-dist/portainer-run-*.tgz oci://ghcr.io/portainer/charts
77 changes: 33 additions & 44 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: release
run-name: '${{ github.event.inputs.version }} release'
run-name: '${{ github.event.inputs.version }} pre-release'

on:
workflow_dispatch:
Expand Down Expand Up @@ -27,11 +27,35 @@ jobs:
- name: '[validation] check server syntax'
run: node --check server/server.js

release:
name: create a pre-release
validate-chart:
name: validate-chart
runs-on: ubuntu-latest
needs: [validate]
steps:
- name: '[preparation] checkout the current branch'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: '[preparation] set up helm'
uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # v5.0.1

- name: '[validation] lint chart'
run: helm lint chart/

- name: '[validation] template chart (dry-run render)'
run: helm template portainer-run chart/ > /dev/null

create-release:
name: create-release
runs-on: ubuntu-latest
needs: [validate, validate-chart]
outputs:
version: ${{ steps.normalize.outputs.value }}
steps:
- name: '[preparation] normalize version'
id: normalize
run: |
version="${{ github.event.inputs.version }}"
echo "value=${version#v}" >> "$GITHUB_OUTPUT"

- name: '[execution] create a pre-release'
run: |
gh release create \
Expand All @@ -44,10 +68,10 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

build:
name: build and push docker image
publish-images:
name: publish-images
runs-on: ubuntu-latest
needs: [release]
needs: [create-release]
steps:
# Exchange the org's GitHub App credentials for a short-lived, narrowly
# scoped installation token so checkout can pull the private design-system
Expand Down Expand Up @@ -89,42 +113,7 @@ jobs:
push: true
platforms: linux/amd64,linux/arm64
build-args: |
PORTAINER_RUN_VERSION=${{ github.event.inputs.version }}
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.event.inputs.version }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
PORTAINER_RUN_VERSION=${{ needs.create-release.outputs.version }}
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.create-release.outputs.version }}
sbom: true
provenance: mode=max

publish-chart:
name: publish helm chart
runs-on: ubuntu-latest
needs: [release]
permissions:
contents: read
packages: write
steps:
- name: '[preparation] checkout the current branch'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: '[preparation] set up Helm'
uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # v5.0.1

- name: '[validation] lint chart'
run: helm lint chart/

- name: '[validation] template chart (dry-run render)'
run: helm template portainer-run chart/ > /dev/null

- name: '[execution] package chart'
run: |
helm package chart/ \
--version "${{ github.event.inputs.version }}" \
--app-version "${{ github.event.inputs.version }}" \
-d /tmp/chart-dist

- name: '[execution] log in to GHCR'
run: echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin

- name: '[execution] push chart'
run: helm push /tmp/chart-dist/portainer-run-*.tgz oci://ghcr.io/portainer/charts
11 changes: 7 additions & 4 deletions chart/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ name: portainer-run
description: Portainer-Run — AI-assisted deployment companion for Portainer, served as a Portainer addon.
type: application

# Chart version — SemVer 2 (three segments). Bump on any change to the chart
# or its templates, independently of the app version below.
version: 1.3.0
# Chart version — SemVer 2 (three segments). Bump on a change to the chart
# or its templates alongside a release, and keep it pinned to the appVersion.
#
# The `promote-release` github action will override the version and the appVersion
# with the github release version.
version: 1.2.9

# Application version — the Portainer-Run release this chart ships. Free-form,
# so it carries the full release string. Used as the image tag when
# image.tag is left empty.
appVersion: '1.2.8'
appVersion: '1.2.9'