diff --git a/.gitea/workflows/publish-helm-charts.yaml b/.gitea/workflows/publish-helm-charts.yaml new file mode 100644 index 0000000..78b4dcf --- /dev/null +++ b/.gitea/workflows/publish-helm-charts.yaml @@ -0,0 +1,145 @@ +name: Publish Helm Charts + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + publish: + runs-on: ubuntu-docker + container: + image: alpine/helm:3.15.4 + env: + HELM_PUSH_TOKEN: ${{ secrets.GITEA_HELM_TOKEN }} + HELM_PUSH_USERNAME: ${{ secrets.HELM_USERNAME }} + HELM_PUSH_PASSWORD: ${{ secrets.HELM_PASSWORD }} + HELM_REGISTRY_OWNER: ${{ secrets.HELM_OWNER }} + steps: + - name: Install Required Tools + shell: sh + run: | + set -eu + apk add --no-cache bash git curl + + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Detect Charts With Version Bump + id: detect + shell: bash + run: | + set -euo pipefail + + if [ -n "${{ github.event.before || '' }}" ] && [ "${{ github.event.before || '' }}" != "0000000000000000000000000000000000000000" ]; then + BASE_SHA="${{ github.event.before }}" + else + BASE_SHA="$(git rev-parse HEAD~1 2>/dev/null || true)" + fi + + CHART_DIRS="$(find . -mindepth 2 -maxdepth 2 -type f -name Chart.yaml -printf '%h\n' | sed 's|^\./||' | sort)" + if [ -z "$CHART_DIRS" ]; then + echo "No chart directories found." + echo "charts=" >> "$GITHUB_OUTPUT" + exit 0 + fi + + CHANGED_CHARTS="" + for chart_dir in $CHART_DIRS; do + chart_file="$chart_dir/Chart.yaml" + current_version="$(awk -F': *' '$1=="version"{gsub(/\"/,"",$2); print $2; exit}' "$chart_file")" + if [ -z "$current_version" ]; then + echo "Skipping $chart_dir because version is missing in Chart.yaml" + continue + fi + + previous_version="" + if [ -n "$BASE_SHA" ] && git cat-file -e "$BASE_SHA:$chart_file" 2>/dev/null; then + previous_version="$(git show "$BASE_SHA:$chart_file" | awk -F': *' '$1=="version"{gsub(/\"/,"",$2); print $2; exit}')" + fi + + if [ -z "$previous_version" ] || [ "$previous_version" != "$current_version" ]; then + CHANGED_CHARTS+="$chart_dir " + echo "Will publish $chart_dir (version: ${previous_version:-} -> $current_version)" + else + echo "Skipping $chart_dir (version unchanged: $current_version)" + fi + done + + CHANGED_CHARTS="$(echo "$CHANGED_CHARTS" | xargs || true)" + echo "charts=$CHANGED_CHARTS" >> "$GITHUB_OUTPUT" + + - name: Package And Publish Changed Charts + if: steps.detect.outputs.charts != '' + shell: bash + env: + CHANGED_CHARTS: ${{ steps.detect.outputs.charts }} + run: | + set -euo pipefail + + AUTH_MODE="" + AUTH_ARGS=() + if [ -n "${HELM_PUSH_USERNAME:-}" ] && [ -n "${HELM_PUSH_PASSWORD:-}" ]; then + AUTH_MODE="basic" + AUTH_ARGS=(--user "${HELM_PUSH_USERNAME}:${HELM_PUSH_PASSWORD}") + elif [ -n "${HELM_PUSH_USERNAME:-}" ] && [ -n "${HELM_PUSH_TOKEN:-}" ]; then + AUTH_MODE="basic-token" + AUTH_ARGS=(--user "${HELM_PUSH_USERNAME}:${HELM_PUSH_TOKEN}") + elif [ -n "${HELM_PUSH_TOKEN:-}" ]; then + AUTH_MODE="token-header" + AUTH_ARGS=(-H "Authorization: token ${HELM_PUSH_TOKEN}") + else + echo "Missing auth secrets. Set GITEA_HELM_USERNAME/GITEA_HELM_PASSWORD (recommended) or GITEA_HELM_TOKEN." + exit 1 + fi + + echo "Using auth mode: $AUTH_MODE" + + SERVER_URL="${GITHUB_SERVER_URL:-${GITEA_SERVER_URL:-}}" + if [ -z "$SERVER_URL" ]; then + echo "Could not resolve Gitea server URL from GITHUB_SERVER_URL/GITEA_SERVER_URL" + exit 1 + fi + SERVER_URL="${SERVER_URL%/}" + + OWNER="${HELM_REGISTRY_OWNER:-${GITHUB_REPOSITORY_OWNER:-}}" + if [ -z "$OWNER" ]; then + echo "Could not resolve package owner. Set secret GITEA_HELM_OWNER." + exit 1 + fi + + UPLOAD_URL="$SERVER_URL/api/packages/$OWNER/helm/api/charts" + mkdir -p .chart-dist + + for chart_dir in $CHANGED_CHARTS; do + echo "Packaging $chart_dir" + helm dependency update "$chart_dir" || true + helm lint "$chart_dir" + helm package "$chart_dir" --destination .chart-dist + + package_file="$(ls -t .chart-dist/*.tgz | head -n1)" + echo "Publishing $package_file to $UPLOAD_URL" + + http_code="$(curl -sS -o /tmp/publish-response.txt -w '%{http_code}' \ + -X POST \ + "${AUTH_ARGS[@]}" \ + --upload-file "$package_file" \ + "$UPLOAD_URL")" + + if [ "$http_code" = "201" ] || [ "$http_code" = "200" ]; then + echo "Published $(basename "$package_file")" + elif [ "$http_code" = "409" ]; then + echo "Chart already exists, skipping: $(basename "$package_file")" + else + echo "Failed to publish $(basename "$package_file") (HTTP $http_code)" + cat /tmp/publish-response.txt || true + exit 1 + fi + done + + - name: No Version Bumps Detected + if: steps.detect.outputs.charts == '' + run: echo "No chart versions changed, skipping publish."