ci: publish next Helm charts

pull/370/head
zijiren233 2 months ago
parent effdf66255
commit aafe321e23
No known key found for this signature in database
GPG Key ID: 534E082AAA9B39DC

@ -24,6 +24,7 @@ jobs:
runs-on: ubuntu-latest
outputs:
meta-images: ${{ steps.meta-images.outputs.value }}
image-tag: ${{ steps.meta-images.outputs.image-tag }}
steps:
- name: Build image metadata inputs
id: meta-images
@ -33,6 +34,7 @@ jobs:
DOCKERHUB_REPOSITORY: ${{ vars.DOCKERHUB_REPOSITORY || secrets.DOCKERHUB_REPOSITORY }}
DEFAULT_REPOSITORY_NAME: ${{ github.event.repository.name }}
run: |
image_tag="sha-${GITHUB_SHA::7}"
if [ -n "$DOCKERHUB_REPOSITORY" ]; then
case "$DOCKERHUB_REPOSITORY" in
*/*)
@ -46,6 +48,7 @@ jobs:
dockerhub_repository="$DOCKERHUB_USERNAME/$DEFAULT_REPOSITORY_NAME"
fi
{
echo "image-tag=$image_tag"
echo 'value<<EOF'
echo "ghcr.io/$GHCR_REPOSITORY"
if [ -n "$dockerhub_repository" ]; then
@ -89,7 +92,7 @@ jobs:
type=ref,event=tag
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
type=raw,value=${{ needs.docker-prepare.outputs.image-tag }}
secrets:
registry-auths: |
- registry: ghcr.io
@ -98,3 +101,23 @@ jobs:
${{ (vars.DOCKERHUB_USERNAME || secrets.DOCKERHUB_USERNAME) != '' && format('- registry: docker.io
username: {0}
password: {1}', vars.DOCKERHUB_USERNAME || secrets.DOCKERHUB_USERNAME, secrets.DOCKERHUB_PASSWORD) || '' }}
helm:
name: Publish next Helm Chart
if: github.event_name == 'push' && github.ref == 'refs/heads/next'
needs:
- docker-prepare
- docker-build
permissions:
contents: read
packages: write
uses: ./.github/workflows/helm.yml
with:
channel: next
image-tag: ${{ needs.docker-prepare.outputs.image-tag }}
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
HELM_OCI_NAMESPACE: ${{ secrets.HELM_OCI_NAMESPACE }}
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_REPOSITORY: ${{ secrets.DOCKERHUB_REPOSITORY }}
DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}

@ -5,7 +5,18 @@ on:
inputs:
release-tag:
description: "Release tag, for example v0.2.0"
required: true
required: false
default: ""
type: string
channel:
description: "Development channel, for example next"
required: false
default: ""
type: string
image-tag:
description: "Image tag produced by the calling Docker workflow"
required: false
default: ""
type: string
secrets:
token:
@ -45,11 +56,16 @@ jobs:
- name: Install protobuf compiler
run: sudo apt-get update && sudo apt-get install -y protobuf-compiler
- name: Validate source chart
run: make validate-helm
- name: Read chart metadata
id: chart
shell: bash
env:
RELEASE_TAG: ${{ inputs.release-tag }}
CHANNEL: ${{ inputs.channel }}
IMAGE_TAG: ${{ inputs.image-tag }}
GHCR_REPOSITORY: ${{ github.repository }}
HELM_OCI_NAMESPACE: ${{ vars.HELM_OCI_NAMESPACE || secrets.HELM_OCI_NAMESPACE }}
DOCKERHUB_USERNAME: ${{ vars.DOCKERHUB_USERNAME || secrets.DOCKERHUB_USERNAME }}
@ -65,20 +81,50 @@ jobs:
exit 1
fi
tag_version="${RELEASE_TAG#v}"
if [ "$chart_version" != "$tag_version" ]; then
echo "Chart version ($chart_version) must match release tag ($tag_version)." >&2
if [ -n "$RELEASE_TAG" ] && [ -n "$CHANNEL" ]; then
echo "release-tag and channel are mutually exclusive." >&2
exit 1
fi
if [ "$app_version" != "$tag_version" ]; then
echo "Chart appVersion ($app_version) must match release tag ($tag_version)." >&2
if [ -z "$RELEASE_TAG" ] && [ -z "$CHANNEL" ]; then
echo "Either release-tag or channel is required." >&2
exit 1
fi
if [ "$cargo_version" != "$tag_version" ]; then
echo "Cargo workspace version ($cargo_version) must match release tag ($tag_version)." >&2
if [ "$chart_version" != "$cargo_version" ] || [ "$app_version" != "$cargo_version" ]; then
echo "Source chart version ($chart_version), appVersion ($app_version), and Cargo workspace version ($cargo_version) must match." >&2
exit 1
fi
if [ -n "$RELEASE_TAG" ]; then
tag_version="${RELEASE_TAG#v}"
if [ "$chart_version" != "$tag_version" ]; then
echo "Chart version ($chart_version) must match release tag ($tag_version)." >&2
exit 1
fi
publish_version="$chart_version"
publish_app_version="$app_version"
publish_image_tag="${IMAGE_TAG:-$tag_version}"
else
if ! [[ "$CHANNEL" =~ ^[0-9A-Za-z-]+$ ]]; then
echo "Development channel must contain only letters, digits, and hyphens." >&2
exit 1
fi
if ! [[ "$IMAGE_TAG" =~ ^[0-9A-Za-z_][0-9A-Za-z._-]{0,127}$ ]]; then
echo "Development image-tag must be a valid OCI image tag." >&2
exit 1
fi
short_sha="${GITHUB_SHA::7}"
version_suffix="$CHANNEL.${GITHUB_RUN_NUMBER}.${GITHUB_RUN_ATTEMPT}.g$short_sha"
if [[ "$chart_version" == *-* ]]; then
publish_version="$chart_version.$version_suffix"
else
publish_version="$chart_version-$version_suffix"
fi
publish_app_version="$IMAGE_TAG"
publish_image_tag="$IMAGE_TAG"
fi
repo="$(printf '%s' "${GITHUB_REPOSITORY#*/}" | tr '[:upper:]' '[:lower:]')"
if [ -n "$DOCKERHUB_REPOSITORY" ]; then
@ -96,8 +142,9 @@ jobs:
{
echo "name=$chart_name"
echo "version=$chart_version"
echo "app_version=$app_version"
echo "version=$publish_version"
echo "app_version=$publish_app_version"
echo "image_tag=$publish_image_tag"
echo "dockerhub_username=$DOCKERHUB_USERNAME"
echo 'oci_repos<<EOF'
if [ -n "$HELM_OCI_NAMESPACE" ]; then
@ -111,24 +158,56 @@ jobs:
echo 'EOF'
} >> "$GITHUB_OUTPUT"
- name: Set release image repository
- name: Set published chart and image metadata
env:
PUBLISH_CHART_VERSION: ${{ steps.chart.outputs.version }}
PUBLISH_APP_VERSION: ${{ steps.chart.outputs.app_version }}
PUBLISH_IMAGE_REPOSITORY: ${{ github.repository }}
PUBLISH_IMAGE_TAG: ${{ steps.chart.outputs.image_tag }}
run: |
ruby <<'RUBY'
require "yaml"
path = "helm/synctv/values.yaml"
values = YAML.load_file(path)
chart_path = "helm/synctv/Chart.yaml"
chart = YAML.load_file(chart_path)
chart["version"] = ENV.fetch("PUBLISH_CHART_VERSION")
chart["appVersion"] = ENV.fetch("PUBLISH_APP_VERSION")
File.write(chart_path, YAML.dump(chart))
values_path = "helm/synctv/values.yaml"
values = YAML.load_file(values_path)
image = values.fetch("image")
image["registry"] = "ghcr.io"
image["repository"] = ENV.fetch("PUBLISH_IMAGE_REPOSITORY").downcase
File.write(path, YAML.dump(values))
puts "OCI release image: #{image['registry']}/#{image['repository']}"
image["tag"] = ENV.fetch("PUBLISH_IMAGE_TAG")
File.write(values_path, YAML.dump(values))
puts "OCI chart version: #{chart['version']}"
puts "OCI chart default image: #{image['registry']}/#{image['repository']}:#{image['tag']}"
RUBY
- name: Validate chart
run: make validate-helm
- name: Validate published chart
env:
PUBLISH_IMAGE_REPOSITORY: ${{ github.repository }}
PUBLISH_IMAGE_TAG: ${{ steps.chart.outputs.image_tag }}
run: |
helm lint ./helm/synctv
rendered_image="$(helm template synctv ./helm/synctv --namespace synctv | ruby -ryaml -e '
YAML.load_stream(STDIN.read).compact.each do |document|
next unless document["kind"] == "Deployment"
containers = document.dig("spec", "template", "spec", "containers") || []
container = containers.find { |item| item["name"] == "synctv" }
if container
puts container.fetch("image")
exit
end
end
abort "SyncTV Deployment image was not rendered"
')"
expected_image="ghcr.io/${PUBLISH_IMAGE_REPOSITORY,,}:$PUBLISH_IMAGE_TAG"
if [ "$rendered_image" != "$expected_image" ]; then
echo "Rendered image ($rendered_image) must match published image ($expected_image)." >&2
exit 1
fi
- name: Package chart
run: |

@ -147,6 +147,13 @@ Return the gRPC service name
{{- include "synctv.nameWithSuffix" (list (include "synctv.fullname" .) "grpc") }}
{{- end }}
{{/*
Return the health service name
*/}}
{{- define "synctv.healthServiceName" -}}
{{- include "synctv.nameWithSuffix" (list (include "synctv.fullname" .) "health") }}
{{- end }}
{{/*
Return the RTMP service name
*/}}

@ -37,7 +37,7 @@ spec:
apiVersion: v1
kind: Service
metadata:
name: {{ include "synctv.fullname" . }}-health
name: {{ include "synctv.healthServiceName" . }}
labels:
{{- include "synctv.labels" . | nindent 4 }}
app.kubernetes.io/component: health

Loading…
Cancel
Save