diff --git a/.github/scripts/cr.sh b/.github/scripts/cr.sh new file mode 100644 index 000000000000..596e278a9dcb --- /dev/null +++ b/.github/scripts/cr.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +DEFAULT_CHART_RELEASER_VERSION=v1.6.1 +DEFAULT_CHARTS_DIR=charts +MAX_CONCURRENT_JOBS=10 + +main() { + local version="$DEFAULT_CHART_RELEASER_VERSION" + local quay_token= + local config="cr.yaml" + local charts_dir="$DEFAULT_CHARTS_DIR" + + parse_command_line "$@" + + : "${CR_TOKEN:?Environment variable CR_TOKEN must be set}" + : "${quay_token:?Quay token must be provided}" + + echo "Packaging and uploading charts..." + job_count=0 + for train in "$charts_dir"/*; do + local train_name=$(basename "$train") + + echo "Processing train: ${train_name}" + if [[ -d "$train" ]]; then + for chart in "$train"/*; do + if [[ -d "$chart" ]]; then + process_chart "$chart" & + job_count=$((job_count + 1)) + + # Control concurrency: wait if we hit the max concurrent job limit + if (( job_count >= MAX_CONCURRENT_JOBS )); then + wait -n # Wait for at least one job to finish + job_count=$((job_count - 1)) + fi + fi + done + fi + done + + # Wait for any remaining background jobs to finish + wait +} + +process_chart() { + local chart="$1" + local chart_name=$(basename "$chart") + local chart_version=$(grep '^version:' "$chart/Chart.yaml" | awk '{print $2}') + echo "Processing: ${chart_name}, version ${chart_version}" + + # Check if the OCI tag exists + if check_existing_tag "$chart_name" "$chart_version"; then + echo "Skipping packaging of $chart because the version $chart_version already exists in OCI." + else + package_chart "$chart" + upload_chart "$chart" & + fi +} + +parse_command_line() { + while :; do + case "${1:-}" in + --quay-token) + if [[ -n "${2:-}" ]]; then + quay_token="$2" + shift + else + echo "ERROR: '--quay-token' cannot be empty." >&2 + exit 1 + fi + ;; + *) + break + ;; + esac + shift + done +} + +check_existing_tag() { + local chart_name="$1" + local tag="$2" + + echo "Checking if tag '$tag' exists for chart '$chart_name' on OCI..." + + # Query the OCI registry for existing tags + local response + response=$(curl -s -H "Authorization: Bearer ${quay_token}" \ + "https://quay.io/api/v1/repository/truecharts/${chart_name}/tag/?specificTag=${tag}") + + if ! echo "$response" | jq . > /dev/null 2>&1; then + echo "Error: Invalid JSON response from the server." + return 2 + fi + + local tag_exists + tag_exists=$(echo "$response" | jq -r --arg tag "$tag" '.tags[]? | select(.name == $tag) | .name') + + if [[ "$tag_exists" == "$tag" ]]; then + echo "Tag '$tag' already exists for chart '$chart_name'." + return 0 + else + echo "Tag '$tag' does not exist for chart '$chart_name'." + return 1 + fi +} + +package_chart() { + local chart="$1" + local args=("$chart" --package-path .cr-release-packages) + if [[ -n "$config" ]]; then + args+=(--config "$config") + fi + + echo "Packaging chart '$chart'..." + cr package "${args[@]}" +} + +upload_chart() { + local chart="$1" + local chart_name=$(basename "$chart") + local chart_version=$(grep '^version:' "$chart/Chart.yaml" | awk '{print $2}') + local pkg=".cr-release-packages/${chart_name}-${chart_version}.tgz" + + if [[ -f "$pkg" ]]; then + echo "Uploading $chart_name version $chart_version to OCI..." + helm push "$pkg" oci://quay.io/truecharts || echo "Failed to upload $pkg to OCI" + curl -X POST -H "Content-Type: application/json" -d '{"visibility": "public"}' -H "Authorization: Bearer ${quay_token}" "https://quay.io/api/v1/repository/truecharts/$chart_name/changevisibility" || echo "Failed to set $pkg to public on OCI" + else + echo "Package $pkg not found, skipping upload." + fi +} + +main "$@" \ No newline at end of file diff --git a/.github/workflows/charts-release.yaml b/.github/workflows/charts-release.yaml index eac99b65b4fe..29f88c63f5ec 100644 --- a/.github/workflows/charts-release.yaml +++ b/.github/workflows/charts-release.yaml @@ -52,14 +52,6 @@ jobs: ./charttool genchangelog "$REPO_PATH" "$TEMPLATE_PATH" "$OUTPUT_DIR" gzip "$JSON_FILE" --best - - name: Checkout Helm-Staging - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4 - with: - fetch-depth: 1 - repository: truecharts/helm-staging - token: ${{ secrets.BOT_TOKEN }} - path: helm - - name: Fix Pre-Commit issues shell: bash run: | @@ -74,17 +66,48 @@ jobs: mkdir helm/charts cp -rf charts helm echo "Copying changelogs to helm" - cp -r ./changelogs/** ./helm/charts/ - - - name: Commit Helm Changes + cp -r ./changelogs/** ./charts/ + + - name: Install Helm + uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # tag=v3 + with: + version: v3.14.0 + + # Optional step if GPG signing is used + - name: Prepare GPG key run: | - cd helm - git config user.name "TrueCharts-Bot" - git config user.email "bot@truecharts.org" - git add --all - git commit -sm "Commit released Helm Charts for TrueCharts" || exit 0 - git push - cd - + gpg_dir=.cr-gpg + mkdir "$gpg_dir" + keyring="$gpg_dir/secring.gpg" + base64 -d <<< "$GPG_KEYRING_BASE64" > "$keyring" + passphrase_file="$gpg_dir/passphrase" + echo "$GPG_PASSPHRASE" > "$passphrase_file" + echo "CR_PASSPHRASE_FILE=$passphrase_file" >> "$GITHUB_ENV" + echo "CR_KEYRING=$keyring" >> "$GITHUB_ENV" + env: + GPG_KEYRING_BASE64: "${{ secrets.GPG_KEYRING_BASE64 }}" + GPG_PASSPHRASE: "${{ secrets.GPG_PASSPHRASE }}" + + - name: Helm | Login + shell: bash + run: echo ${{ secrets.QUAY_SECRET }} | helm registry login -u ${{ secrets.QUAY_USER }} --password-stdin quay.io + + - name: Release Charts + shell: bash + env: + CR_TOKEN: "${{ secrets.BOT_TOKEN }}" + CR_SKIP_EXISTING: "true" + run: | + owner=$(cut -d '/' -f 1 <<< "$GITHUB_REPOSITORY") + repo=$(cut -d '/' -f 2 <<< "$GITHUB_REPOSITORY") + install="$RUNNER_TOOL_CACHE/cr/${{ inputs.version }}/$(uname -m)" + echo "$install" >> "$GITHUB_PATH" + ./.github/scripts/cr.sh --quay-token "${{ secrets.QUAY_TOKEN }}" --instal-dir $install + + - name: Helm | Logout + shell: bash + run: helm registry logout quay.io + - name: Checkout uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4 diff --git a/cr.yaml b/cr.yaml index 61040e080173..558fc88ff910 100644 --- a/cr.yaml +++ b/cr.yaml @@ -2,9 +2,7 @@ owner: truecharts git-repo: charts repo: charts charts-dir: charts/* -charts_repo_url: "https://deps.truecharts.org" SkipExisting: true -skipExisting: true # Set to true for GPG signing sign: true # UID of the GPG key to use