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
168 changes: 168 additions & 0 deletions .github/workflows/release-graylog.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
name: Release Graylog Chart

# Packages the chart for a release release-please has already cut, attaches the
# tarball to that release, and merges one entry into the Helm repository index on
# gh-pages.
#
# This does not use chart-releaser. chart-releaser names its release
# "{{ .Name }}-{{ .Version }}", which is exactly the graylog-X.Y.Z tag
# release-please already owns, so it finds the release present and, running with
# skip_existing, declines to upload anything. The run goes green and no chart
# ships.
#
# release-please.yaml calls this workflow. A tag or release trigger would never
# fire, because refs created with GITHUB_TOKEN raise no workflow events. Do not
# turn this into a release-triggered workflow.

on:
workflow_call:
inputs:
tag:
description: Release tag to attach the packaged chart to
required: true
type: string
workflow_dispatch:
inputs:
tag:
description: Existing release tag to attach the packaged chart to (e.g. graylog-2.0.0)
required: true
type: string

permissions:
contents: write

concurrency:
# Publishes read-modify-write one shared index.yaml, so they must not overlap.
group: publish-chart
cancel-in-progress: false

jobs:
publish:
runs-on: ubuntu-latest
env:
CHART_DIR: charts/graylog
PACKAGE_DIR: .cr-release-packages
TAG: ${{ inputs.tag }}
steps:
# This workflow writes release assets and rewrites the published Helm
# index. A fork running it through workflow_dispatch would publish into its
# own releases while claiming the upstream index URL, so it refuses to run
# anywhere else.
- name: Guard against publishing outside the chart repository
run: |
if [[ "${{ github.repository }}" != "Graylog2/graylog-helm" ]]; then
echo "::error::refusing to publish charts from ${{ github.repository }}"
exit 1
fi
echo "publishing within ${{ github.repository }}"

- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ inputs.tag }}

- name: Check out the Helm repository index
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: gh-pages
path: gh-pages

- uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # v5.0.1
with:
version: v3.16.4

# release-please renders release notes as Markdown only, so no updater can
# write changelog content into a YAML field. This step generates the
# annotation from the CHANGELOG.md of the tag being published and never
# commits it. ArtifactHub reads it out of the packaged tarball it fetches
# through index.yaml. CHANGELOG.md stays the single source of truth, and
# stays editable on the release PR like the rest of the release.
- name: Generate the artifacthub.io/changes annotation
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python3 .github/scripts/artifacthub_changes.py \
--chart-dir "$CHART_DIR" --repo "$GITHUB_REPOSITORY"
helm show chart "$CHART_DIR" | yq e '.annotations."artifacthub.io/changes"' -

- name: Package the chart
run: |
helm package "$CHART_DIR" --destination "$PACKAGE_DIR"
ls -l "$PACKAGE_DIR"

# The tag encodes the version release-please released. The chart must
# agree, or the index advertises a version the package does not contain.
- name: Verify the packaged version matches the tag
run: |
chart_version="$(helm show chart "$CHART_DIR" | yq e '.version' -)"
tag_version="${TAG#graylog-}"
if [[ "$chart_version" != "$tag_version" ]]; then
echo "::error::Chart.yaml is $chart_version but the tag says $tag_version"
exit 1
fi
echo "version=$chart_version" >> "$GITHUB_ENV"

- name: Attach the package to the release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release upload "$TAG" "$PACKAGE_DIR"/*.tgz --clobber

# This merges the index and never regenerates it. The release assets serve
# the packages, so gh-pages holds no tarballs, and regenerating the index
# from that directory would drop every historical entry. `--merge` keeps
# entries whose tarball is absent and refreshes the URL of the version
# being published.
- name: Merge the new version into the Helm repository index
run: |
index=gh-pages/index.yaml
before="$(yq e '.entries.graylog[] | .version + " " + .urls[0]' "$index" | sort | sed '/^$/d')"

helm repo index "$PACKAGE_DIR" \
--merge "$index" \
--url "https://github.com/${GITHUB_REPOSITORY}/releases/download/${TAG}"

after="$(yq e '.entries.graylog[] | .version + " " + .urls[0]' "$PACKAGE_DIR/index.yaml" | sort | sed '/^$/d')"

# Every version and URL pair that already exists must survive verbatim.
# The version being published is the one exception, because its URL is
# refreshed on purpose. This backstops the one mistake that cannot be
# walked back quietly, regenerating the index instead of merging it,
# which drops every version whose tarball is not on disk. None of them
# are.
lost="$(comm -23 <(printf '%s\n' "$before" | grep -v "^${version} " || true) <(printf '%s\n' "$after") || true)"
if [[ -n "$lost" ]]; then
echo "::error::index.yaml would lose or rewrite existing entries:"
printf '%s\n' "$lost"
exit 1
fi

cp "$PACKAGE_DIR/index.yaml" "$index"
printf '%s\n' "$after" | sed 's/^/ /'

- name: Publish the index
run: |
cd gh-pages
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
# index.yaml only. artifacthub-repo.yml carries ArtifactHub ownership
# and nothing here should touch it.
git add index.yaml
if git diff --cached --quiet; then
echo "Helm repository already publishes ${version}"
exit 0
fi
git commit -m "chore: publish graylog ${version} to the Helm repository"
git push

- name: Summary
run: |
{
echo "### Published \`graylog\` ${version}"
echo
echo '```'
echo "helm repo add graylog https://graylog2.github.io/graylog-helm"
echo "helm repo update graylog"
echo "helm install graylog graylog/graylog --version ${version}"
echo '```'
echo
echo "Tarball attached to [\`${TAG}\`](${{ github.server_url }}/${{ github.repository }}/releases/tag/${TAG})."
} >> "$GITHUB_STEP_SUMMARY"
37 changes: 24 additions & 13 deletions .github/workflows/release-please.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ concurrency:
jobs:
release-please:
runs-on: ubuntu-latest
outputs:
# Per-package outputs are keyed by package path.
graylog-released: ${{ steps.release.outputs['charts/graylog--release_created'] }}
graylog-tag: ${{ steps.release.outputs['charts/graylog--tag_name'] }}
graylog-version: ${{ steps.release.outputs['charts/graylog--version'] }}
paths-released: ${{ steps.release.outputs.paths_released }}
steps:
- uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5
id: release
Expand All @@ -25,17 +31,22 @@ jobs:
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
target-branch: main
# PR-only mode: chart-releaser (release.yaml) still owns the tag, the
# release and the index entry. Both use the name graylog-X.Y.Z, so if
# release-please created the release first, chart-releaser would find
# it present and — running with skip_existing: true — silently decline
# to upload the chart package. Removed in the publishing cutover, when
# chart-releaser is retired.
skip-github-release: true

# No artifacthub.io/changes step here on purpose. The annotation is
# generated from CHANGELOG.md when the chart is packaged, not committed
# onto the release PR: a commit here would race release-please's own
# force-push of the branch, and it would make hand edits to the annotation
# depend on being the last change before the merge. See
# .github/scripts/artifacthub_changes.py.
# No artifacthub.io/changes step here on purpose. release-graylog.yaml
# generates the annotation from CHANGELOG.md when it packages the chart,
# rather than committing it onto the release PR. A commit here would race
# release-please's own force-push of the branch, and it would make any hand
# edit to the annotation depend on being the last change before the merge.
# See .github/scripts/artifacthub_changes.py.

# Linked to the release rather than to a path filter or a tag push. Refs
# created with GITHUB_TOKEN raise no events, so only the release-please run
# itself knows a release happened.
publish-chart:
needs: release-please
if: needs.release-please.outputs.graylog-released == 'true'
uses: ./.github/workflows/release-graylog.yaml
permissions:
contents: write
with:
tag: ${{ needs.release-please.outputs.graylog-tag }}
30 changes: 0 additions & 30 deletions .github/workflows/release.yaml

This file was deleted.