Skip to content

Commit

Permalink
feat(gh-action): add chart deploy (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
whg517 authored Oct 18, 2024
1 parent 00a9d4a commit af1f77f
Show file tree
Hide file tree
Showing 7 changed files with 319 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .github/configs/ct-install.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## Reference: https://github.com/helm/chart-testing/blob/master/doc/ct_lint-and-install.md
# Don't add the 'debug' attribute, otherwise the workflow won't work anymore
# Only Used for the CT Install Stage
remote: origin
target-branch: main
chart-dirs:
- charts
chart-repos: []
helm-extra-args: "--timeout 600s"
validate-chart-schema: false
validate-maintainers: true
validate-yaml: true
exclude-deprecated: true
excluded-charts: []
13 changes: 13 additions & 0 deletions .github/configs/ct-lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## Reference: https://github.com/helm/chart-testing/blob/master/doc/ct_lint-and-install.md
# Don't add the 'debug' attribute, otherwise the workflow won't work anymore
# Only Used for the CT Lint Stage
remote: origin
target-branch: main
chart-dirs:
- charts
chart-repos: []
validate-chart-schema: false
validate-maintainers: true
validate-yaml: true
exclude-deprecated: true
excluded-charts: []
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file

version: 2
updates:
- package-ecosystem: "gomod" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
59 changes: 59 additions & 0 deletions .github/workflows/lint-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
## Reference: https://github.com/helm/chart-testing-action
name: Linting and Testing
on:
pull_request:
push:

permissions:
contents: read

jobs:
linter-artifacthub:
runs-on: ubuntu-latest
container:
image: public.ecr.aws/artifacthub/ah:v1.14.0
options: --user 1001
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run ah lint
working-directory: ./charts
run: ah lint

lint-test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Helm
uses: azure/[email protected]
- uses: actions/setup-python@v5
with:
python-version: '3.x'
check-latest: true
- name: Setup Chart Linting
id: lint
uses: helm/[email protected]
with:
version: v3.11.0

- name: Run chart-testing (list-changed)
id: list-changed
run: |
changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }})
if [[ -n "$changed" ]]; then
echo "changed=true" >> "$GITHUB_OUTPUT"
fi
- name: Run chart-testing (lint)
if: steps.list-changed.outputs.changed == 'true'
run: ct lint --debug --config ./.github/configs/ct-lint.yaml

- name: Create kind cluster
if: steps.list-changed.outputs.changed == 'true'
uses: helm/[email protected]

- name: Run chart-testing (install)
if: steps.list-changed.outputs.changed == 'true'
run: ct install --config ./.github/configs/ct-install.yaml
45 changes: 45 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Deploy a dev version snapshot of helm chart to GitHub releases, the target version is 0.0.0-dev.
# When re-deploy, the previous release will be replaced.

name: Publish helm chart

on:
push:
branches:
- main
paths:
- "charts/**"

permissions:
contents: read


jobs:
upload-helm-chart:
# if: ${{ github.repository_owner == 'zncdatadev' }}
permissions:
contents: write # for helm/chart-releaser-action to push chart release and create a release
name: Publish helm chart
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "[email protected]"
- name: Helm tool installer
uses: azure/[email protected]
- name: Delete existing release if exists
env:
GH_TOKEN: ${{ github.token }}
run: |
./scripts/delete-release.sh -r ${{ github.repository }}
# TODO: Sign the chart
- name: Run chart-releaser
uses: helm/[email protected]
env:
# set directly parameters to chart-releaser cli
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
CR_INDEX_PATH: "./index.yaml"
4 changes: 4 additions & 0 deletions charts/commons-operator/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ version: 0.0.0-dev
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "0.0.0-dev"

maintainers:
- email: [email protected]
name: whg517
173 changes: 173 additions & 0 deletions scripts/delete-release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
#!/bin/bash
set -euo pipefail

SUPPORT_DELETE_RELEASE_VERSION="0.0.0-dev"

function main () {
local usage="
Usage: delete-release.sh [options]
Delete a release for a Helm chart.
Arguments:
-r, --repository <repo> The GitHub repository to look for Helm charts. Required.
-d, --chart-dir <dir> The directory to look for Helm charts. Default is 'charts'.
-h, --help Display
"

local charts_dir="charts"
local repository

while [[ $# -gt 0 ]]; do
case $1 in
-r|--repository)
repository=$2
shift 2
;;
-d|--chart-dir)
charts_dir=$2
shift 2
;;
-h|--help)
echo "$usage"
exit 0
;;
*)
echo "Unknown argument: $1"
echo "$usage"
exit 1
;;
esac
done

if [[ -z "$repository" ]]; then
echo "Repository is required."
echo "$usage"
exit 1
fi

check_gh_login

local latest_tag=$(lookup_latest_tag)
echo "Discovering changes since $latest_tag..."

local changed_charts=()
readarray -t changed_charts <<<"$(lookup_changed_charts "$latest_tag" "$charts_dir")"

if [[ ${#changed_charts[@]} -eq 0 ]]; then
echo "No changes detected." 1>&2
exit 0
fi

echo "The following charts have changed, and their releases will be deleted: ${changed_charts[*]}" 1>&2
for chart in "${changed_charts[@]}"; do
delete_chart_release "$repository" "$chart"
echo "Deleted release for $chart" 1>&2
done


}

# check_gh_login checks if the user is logged in to GitHub.
# Check gh login status or GH_TOKEN in env
function check_gh_login() {
if gh auth status >/dev/null 2>&1; then
echo "GitHub CLI is authenticated." 1>&2
elif [[ -n "$GH_TOKEN" ]]; then
echo "Using GH_TOKEN from environment." 1>&2
else
echo "Error: Not authenticated with GitHub. Please login using 'gh auth login' or set GH_TOKEN in the environment." >&2
exit 1
fi
}

# lookup_latest_tag looks up the latest tag in the repository.
# Arguments:
# None.
# Returns:
# The latest tag in the repository.
function lookup_latest_tag() {
git fetch --tags >/dev/null 2>&1

if ! git describe --tags --abbrev=0 HEAD~ 2>/dev/null; then
git rev-list --max-parents=0 --first-parent HEAD
fi

}

# filter_charts filters out non-Helm charts from a list of directories.
# Arguments:
# $1: A list of directories.
# Returns:
# A list of directories that contain Helm charts.
function filter_charts() {
while read -r chart; do
[[ ! -d "$chart" ]] && continue
local file="$chart/Chart.yaml"
if [[ -f "$file" ]]; then
# Check chart version support delete
local chart_version=$(yq eval '.version' "$file")
if [[ "$chart_version" == "$SUPPORT_DELETE_RELEASE_VERSION" ]]; then
echo "$chart"
else
echo "Chart version $chart_version is not supported for deletion." >&2
exit 1
fi
else
echo "WARNING: $file is missing, assuming that '$chart' is not a Helm chart. Skipping." 1>&2
fi
done
}

# lookupd_change_charts looks up the Helm charts that have changed in a commit.
# Arguments:
# $1: The commit hash.
# $2: The directory to look for Helm charts.
# Returns:
# A list of helm charts that have changed in the commit.
function lookup_changed_charts() {
local commit="$1"
local charts_dir="$2"
local changed_files

# Get the list of changed files in this commit.
changed_files=$(git diff --find-renames --name-only "$commit" -- "$charts_dir")
local depth=$(($(tr "/" "\n" <<<"$charts_dir" | sed '/^\(\.\)*$/d' | wc -l) + 1))
# Get the list of changed charts.
if [[ -n "$changed_files" ]]; then
cut -d "/" -f "1-$depth" <<<"$changed_files" | uniq | sort -u | filter_charts
else
echo "No changed files found in commit $commit within directory $charts_dir." 1>&2
fi
}

# delete_chart_release deletes a release for a Helm chart.
# Arguments:
# $1: The repository name.
# $2: The changed chart path.
# Returns:
# None.
function delete_chart_release() {
local repository="$1"
local changed_chart="$2"

local chart_name=$(basename "$changed_chart")
local chart_version=$(yq eval '.version' "$changed_chart/Chart.yaml")
local release_name="$chart_name-$chart_version"

echo "Deleting release $release_name for $changed_chart..."
# check chart_version support delete, if not support, raise error
if [[ "$chart_version" != "$SUPPORT_DELETE_RELEASE_VERSION" ]]; then
echo "WARNING: Release $release_name is not supported for deletion. Skipping." 1>&2
return
fi

local release_id=$(gh api -X GET "repos/$repository/releases" | jq -r ".[] | select(.name | startswith(\"$release_name\")) | .id")
if [[ -n "$release_id" ]]; then
gh api -X DELETE "repos/$repository/releases/$release_id"
else
echo "No release found for $release_name." 1>&2
fi
}

main "$@"

0 comments on commit af1f77f

Please sign in to comment.