Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create helm chart repository in gh-pages #1931

Merged
merged 1 commit into from
Nov 22, 2024
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
71 changes: 71 additions & 0 deletions .github/workflows/publish-helm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Publish Helm Charts

on:
release:
types: [published]

jobs:
release:

permissions:
contents: write

runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install Helm
uses: azure/setup-helm@v4

- name: Install Helm HTML Plugin
run: helm plugin install https://github.com/halkeye/helm-repo-html

- name: Build Helm Chart Repo index.yaml
run: |
# this script from main will be gone on gh-pages branch,
# so lets stash it away in a temp directory in the directory above this one
mkdir ../.tmp
mv hack/find_helm_chart_releases_and_create_helm_index.sh ../.tmp/
mv hack/gh-pages.tmpl ../.tmp/

PAGES_BRANCH="gh-pages"

git fetch --all --tags

if git show-ref --verify --quiet refs/heads/$PAGES_BRANCH || git ls-remote --exit-code --heads origin $PAGES_BRANCH; then
# Branch exists
git checkout $PAGES_BRANCH
echo "Checked out existing branch '$PAGES_BRANCH'"
else
# Branch does not exist
git symbolic-ref HEAD refs/heads/$PAGES_BRANCH
rm .git/index
git clean -fdx
echo ".tmp/" > .gitignore
echo "Created and checked out new branch '$PAGES_BRANCH'"
fi

mv ../.tmp ./
.tmp/find_helm_chart_releases_and_create_helm_index.sh
helm repo-html -t .tmp/gh-pages.tmpl

if output=$(git status --porcelain) && [ -z "$output" ]; then
# Working directory clean

echo "No changes to commit"
else
# Uncommitted changes
echo "Changes detected"
git status
echo "Committing..."

git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add -A
git commit -m "update helm chart repository index.yaml"

git push origin gh-pages
fi
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,6 @@ tags
.vscode/*
.history
# End of https://www.gitignore.io/api/go,vim,emacs,visualstudiocode

charts/
.tmp/
97 changes: 97 additions & 0 deletions hack/find_helm_chart_releases_and_create_helm_index.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/bin/bash
set -e

# GitHub Repository and API token
REPO="knative/operator"
CHART_NAME="knative-operator"

# GitHub API URL for releases
GITHUB_API="https://api.github.com/repos/$REPO/releases"

# Create an empty index.yaml file with 2-space indentation
cat > index.yaml <<EOF
apiVersion: v1
entries:
$CHART_NAME:
EOF

# Function to fetch all releases and filter .tgz files
fetch_tgz_assets() {
echo "Fetching release assets from GitHub API..." >&2

# Get response from GitHub API
response=$(curl "$GITHUB_API")

# Check if the response is valid JSON
if ! echo "$response" | jq 1>/dev/null 2>&1; then
echo "(fetch_tgz_assets) Error: The response is not valid JSON. Here's the raw response:" >&2
echo "$response" >&2
exit 1
fi

# Parse the response using jq to get the list of .tgz files
echo "$response" | jq -c '.[] | .assets[] | select(.name | test("'$CHART_NAME'-(v?\\d+\\.\\d+\\.\\d+)\\.tgz")) | {url: .browser_download_url, name: .name, published: .updated_at}'
}

# Function to process each .tgz file and append chart metadata to index.yaml
process_tgz() {
local url=$1
local name=$2
local published=$3

echo "Processing $name from $url" >&2

# Download the .tgz file
curl -L -s -o "$name" "$url"

# Extract the Chart.yaml and values.yaml
tar -xf "$name" "$CHART_NAME/Chart.yaml" "$CHART_NAME/values.yaml"

# Parse description from Chart.yaml
DESCRIPTION=$(yq -r '.description' $CHART_NAME/Chart.yaml)

# Parse version from Chart.yaml (used as appVersion)
CHART_VERSION="$(yq -r '.version' $CHART_NAME/Chart.yaml)"

# Calculate the SHA-256 digest
DIGEST=$(sha256sum "$name" | cut -d' ' -f1)

# Append the chart metadata under the existing $CHART_NAME key
cat >> index.yaml <<EOF
- name: "$CHART_NAME"
apiVersion: v2
version: "v$CHART_VERSION"
appVersion: "$CHART_VERSION"
description: "$DESCRIPTION"
created: "$published"
urls:
- "$url"
digest: "$DIGEST"
EOF

# Cleanup
rm -f "$name"
rm -f $CHART_NAME/Chart.yaml $CHART_NAME/values.yaml
}

# Fetch all .tgz assets
tgz_assets=$(fetch_tgz_assets)

# Loop through all the assets and process them
echo "$tgz_assets" | while read -r asset; do
# Check if each asset is valid JSON
if ! echo "$asset" | jq '.' > /dev/null 2>&1; then
echo "Error: Invalid JSON in asset line. Here's the raw asset line:" >&2
echo "$asset" >&2
continue
fi

# Parse fields from the asset JSON
url=$(echo "$asset" | jq -r '.url')
name=$(echo "$asset" | jq -r '.name' | sed 's/.tgz$//') # Strip ".tgz" from name
published=$(echo "$asset" | jq -r '.published')

process_tgz "$url" "$name" "$published"
done

echo "index.yaml generated successfully!"
108 changes: 108 additions & 0 deletions hack/gh-pages.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Helm Charts - Knative</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f6f8;
color: #2c3e50;
margin: 0;
padding: 20px;
display: flex;
justify-content: center;
}
.container {
max-width: 900px;
width: 100%;
}
h1 {
font-size: 28px;
color: #333;
font-weight: bold;
margin-bottom: 20px;
}
.usage, .chart-list {
background: #fff;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
margin-bottom: 20px;
}
.usage-code {
background: #333;
color: #fff;
padding: 12px;
border-radius: 5px;
font-family: "Courier New", monospace;
display: block;
font-size: 14px;
}
.chart-item {
margin-bottom: 20px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 8px;
}
.chart-item h2 {
font-size: 18px;
margin: 0;
color: #007d9c;
}
.chart-item a {
color: #007d9c;
text-decoration: none;
font-weight: 500;
}
.chart-versions {
font-size: 14px;
color: #555;
margin-top: 5px;
}
.version-label {
font-weight: bold;
color: #333;
}
.chart-description {
font-size: 14px;
color: #777;
margin-top: 4px;
}
</style>
</head>
<body>

<div class="container">
<h1>Helm Charts</h1>

<div class="usage">
<h2>Usage</h2>
<code class="usage-code">
helm repo add knative-operator https://knative.github.io/operator<br/>
helm show values knative-operator/knative-operator
</code>
</div>

<div class="chart-list">
<h2>Charts</h2>

{{range $entriesKey, $chartEntries := .Entries }}
{{range $chartKey, $chart := $chartEntries }}
<div class="chart-item">
<h2><a href="{{ (index $chart.Urls 0) }}" title="{{ (index $chart.Urls 0) }}">{{ $chart.Name }}</a></h2>
<div class="chart-versions">
<span class="version-label">Chart Version:</span> {{ $chart.Version }} |
<span class="version-label">App Version:</span> {{ $chart.AppVersion }}
</div>
<p class="chart-description">{{ $chart.Description }}</p>
</div>
{{end}}
{{end}}

</div>
</div>

</body>
</html>
Loading