Skip to content

Commit 1dba8c2

Browse files
committed
feat: add helm lint/publish actions
1 parent ff8ade8 commit 1dba8c2

File tree

6 files changed

+300
-11
lines changed

6 files changed

+300
-11
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
name: Helm Chart Lint
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
chart_path:
7+
description: 'Path to Helm chart directory'
8+
required: true
9+
type: string
10+
helm_version:
11+
description: 'Helm version to use'
12+
required: false
13+
type: string
14+
default: 'v3.12.0'
15+
chart_name:
16+
description: 'Chart name for templating (defaults to chart directory name)'
17+
required: false
18+
type: string
19+
default: ''
20+
values_file:
21+
description: 'Path to values file for templating validation'
22+
required: false
23+
type: string
24+
default: ''
25+
runs-on:
26+
type: string
27+
required: false
28+
default: '["self-hosted", "ubuntu-22.04"]'
29+
30+
permissions:
31+
contents: read
32+
33+
jobs:
34+
lint:
35+
name: Lint Helm Chart
36+
runs-on: ${{ fromJSON(inputs.runs-on) }}
37+
timeout-minutes: 10
38+
steps:
39+
- name: Checkout
40+
uses: actions/checkout@v4
41+
42+
- name: Setup Helm
43+
uses: azure/setup-helm@v3
44+
with:
45+
version: ${{ inputs.helm_version }}
46+
47+
- name: Lint chart
48+
run: |
49+
echo "🔍 Linting Helm chart at ${{ inputs.chart_path }}..."
50+
helm lint ${{ inputs.chart_path }}
51+
echo "✅ Chart linting passed"
52+
53+
- name: Template chart
54+
run: |
55+
# Determine chart name (from input or extract from directory)
56+
CHART_NAME="${{ inputs.chart_name }}"
57+
if [ -z "$CHART_NAME" ]; then
58+
CHART_NAME=$(basename ${{ inputs.chart_path }})
59+
fi
60+
61+
echo "📋 Templating chart '$CHART_NAME' with default values..."
62+
63+
# Use custom values file if provided, otherwise use default
64+
VALUES_FLAG=""
65+
if [ -n "${{ inputs.values_file }}" ]; then
66+
VALUES_FLAG="--values ${{ inputs.values_file }}"
67+
elif [ -f "${{ inputs.chart_path }}/values.yaml" ]; then
68+
VALUES_FLAG="--values ${{ inputs.chart_path }}/values.yaml"
69+
fi
70+
71+
helm template "$CHART_NAME" ${{ inputs.chart_path }} $VALUES_FLAG
72+
echo "✅ Chart templating passed"
73+
74+
- name: Package chart (validation only)
75+
run: |
76+
echo "📦 Packaging chart for validation..."
77+
helm package ${{ inputs.chart_path }}
78+
ls -la *.tgz
79+
echo "✅ Chart packaging successful"
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
name: Helm Chart Publish to Harbor
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
chart_path:
7+
description: 'Path to Helm chart directory'
8+
required: true
9+
type: string
10+
chart_name:
11+
description: 'Chart name (used for extracting version from tag)'
12+
required: true
13+
type: string
14+
organization:
15+
description: 'Harbor organization name'
16+
required: true
17+
type: string
18+
registry:
19+
description: 'Harbor registry URL'
20+
required: false
21+
type: string
22+
default: 'registry.mconf.com'
23+
chart_repo:
24+
description: 'Helm chart repository name in Harbor'
25+
required: false
26+
type: string
27+
default: 'helm-charts'
28+
helm_version:
29+
description: 'Helm version to use'
30+
required: false
31+
type: string
32+
default: 'v3.12.0'
33+
tag_prefix:
34+
description: 'Tag prefix to extract version from (e.g., "myapp-helm-chart-" from tag "myapp-helm-chart-1.0.0")'
35+
required: false
36+
type: string
37+
default: ''
38+
runs-on:
39+
type: string
40+
required: false
41+
default: '["self-hosted", "ubuntu-22.04"]'
42+
secrets:
43+
HARBOR_USERNAME:
44+
description: 'Harbor registry username'
45+
required: true
46+
HARBOR_PASSWORD:
47+
description: 'Harbor registry password'
48+
required: true
49+
outputs:
50+
chart_version:
51+
description: 'Published chart version'
52+
value: ${{ jobs.publish.outputs.chart_version }}
53+
chart_url:
54+
description: 'Full chart OCI URL'
55+
value: ${{ jobs.publish.outputs.chart_url }}
56+
57+
permissions:
58+
contents: read
59+
60+
jobs:
61+
publish:
62+
name: Publish Helm Chart
63+
runs-on: ${{ fromJSON(inputs.runs-on) }}
64+
timeout-minutes: 15
65+
outputs:
66+
chart_version: ${{ steps.version.outputs.version }}
67+
chart_url: ${{ steps.publish.outputs.chart_url }}
68+
steps:
69+
- name: Checkout
70+
uses: actions/checkout@v4
71+
72+
- name: Setup Helm
73+
uses: azure/setup-helm@v3
74+
with:
75+
version: ${{ inputs.helm_version }}
76+
77+
- name: Extract version from tag
78+
id: version
79+
run: |
80+
# Extract version from tag
81+
VERSION=${GITHUB_REF#refs/tags/}
82+
83+
# Remove tag prefix if provided (e.g., "myapp-helm-chart-1.0.0" -> "1.0.0")
84+
if [ -n "${{ inputs.tag_prefix }}" ]; then
85+
VERSION=${VERSION#${{ inputs.tag_prefix }}}
86+
else
87+
# Default: remove "{chart_name}-helm-chart-" prefix
88+
VERSION=${VERSION#${{ inputs.chart_name }}-helm-chart-}
89+
fi
90+
91+
echo "📋 Publishing chart version: $VERSION"
92+
echo "version=$VERSION" >> $GITHUB_OUTPUT
93+
94+
- name: Lint chart
95+
run: |
96+
echo "🔍 Linting Helm chart..."
97+
helm lint ${{ inputs.chart_path }}
98+
echo "✅ Chart linting passed"
99+
100+
- name: Package chart
101+
run: |
102+
echo "📦 Packaging Helm chart..."
103+
helm package ${{ inputs.chart_path }}
104+
ls -la *.tgz
105+
echo "✅ Chart packaged successfully"
106+
107+
- name: Login to Harbor
108+
uses: docker/login-action@v3
109+
with:
110+
registry: ${{ inputs.registry }}
111+
username: ${{ secrets.HARBOR_USERNAME }}
112+
password: ${{ secrets.HARBOR_PASSWORD }}
113+
114+
- name: Push to Harbor
115+
id: publish
116+
run: |
117+
CHART_FILE=$(ls ${{ inputs.chart_name }}-*.tgz)
118+
CHART_URL="oci://${{ inputs.registry }}/${{ inputs.organization }}/${{ inputs.chart_repo }}"
119+
120+
echo "🚀 Publishing $CHART_FILE to Harbor..."
121+
helm push "$CHART_FILE" "$CHART_URL"
122+
123+
echo "✅ Chart published successfully to Harbor"
124+
echo "📋 Chart version: ${{ steps.version.outputs.version }}"
125+
echo "📋 Chart repository: $CHART_URL"
126+
echo "chart_url=$CHART_URL" >> $GITHUB_OUTPUT
127+
128+
# Add to job summary
129+
echo "## 📦 Helm Chart Published" >> $GITHUB_STEP_SUMMARY
130+
echo "" >> $GITHUB_STEP_SUMMARY
131+
echo "- **Chart:** \`${{ inputs.chart_name }}\`" >> $GITHUB_STEP_SUMMARY
132+
echo "- **Version:** \`${{ steps.version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
133+
echo "- **Repository:** \`$CHART_URL\`" >> $GITHUB_STEP_SUMMARY
134+
echo "" >> $GITHUB_STEP_SUMMARY
135+
echo "### Install Command" >> $GITHUB_STEP_SUMMARY
136+
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
137+
echo "helm install ${{ inputs.chart_name }} $CHART_URL/${{ inputs.chart_name }} --version ${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
138+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY

README.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,31 @@ Reusable GitHub Actions workflows for CI/CD pipelines across Mconf projects.
66

77
This repository provides a centralized collection of reusable GitHub Actions workflows for building, testing, linting, and deploying applications across multiple programming languages and platforms. All workflows are optimized for self-hosted runners and follow security best practices.
88

9+
## Development Guidelines
10+
11+
Company-wide development practices and standards are documented in the [guidelines/](guidelines/) directory. These guidelines provide:
12+
13+
- **AI Collaboration** - Best practices for working with AI coding tools
14+
- **General Development** - Language-agnostic practices (linting, Makefiles, pre-commit hooks)
15+
- **Language-Specific** - Guidelines for Ruby, Python, Go, and JavaScript
16+
- **Docker** - Container best practices and multi-stage builds
17+
- **Testing** - Testing strategies and AI-assisted test generation
18+
- **Git Workflow** - Commit messages, branching, and pull requests
19+
20+
**Templates:** The [templates/](templates/) directory contains starter configurations (Makefile, AGENTS.md, linter configs, Docker examples) that you can copy to your projects.
21+
22+
See [guidelines/README.md](guidelines/README.md) for a complete index.
23+
924
## Workflow Comparison
1025

1126
| Workflow | Action | Language/Tool | Registry | Security | Coverage | Private Repos | AI | Key Features |
1227
|----------|--------|---------------|----------|----------|----------|---------------|----|--------------|
1328
| **all-build-push-image** | Build+Push | Docker | Harbor | | | | | Multi-platform, metadata extraction, GHA+registry caching |
14-
| **all-build-push-scan-harbor** | Build+Push+Scan | Docker, Trivy | Harbor || || | Auto-detect push/scan, SSH support, Trivy Explorer upload |
29+
| **all-build-push-scan-harbor** | Build+Push+Scan | Docker, Trivy | Harbor || || | Auto-detect push/scan, SSH support, Trivy Explorer upload, custom context/target |
1530
| **all-create-tag** | Release | Git | | | | | | Version validation, annotated tags |
1631
| **all-gen-changelog-ai** | Release | Git, Claude | | | | || PR info gathering, Notion integration, Claude Code |
32+
| **all-helm-lint** | Lint | Helm | | | | | | Chart validation, templating, packaging test |
33+
| **all-helm-publish** | Publish | Helm | Harbor | | | | | OCI registry push, version extraction, GitHub summary |
1734
| **data-py-uv-lint** | Lint | Python, Flake8, Black, isort, uv | | | | | | uv-based dependency management |
1835
| **data-py-uv-tests** | Test | Python, pytest, uv | | || | | uv-based dependency management, configurable pytest markers |
1936
| **lb-go-build** | Build | Go | | | || | CGO, private modules, build-essential |
@@ -102,7 +119,7 @@ This repository provides a centralized collection of reusable GitHub Actions wor
102119
Builds and pushes Docker images to Harbor with automatic tagging and caching. Supports multi-platform builds and optional DockerHub login for base images.
103120
**Usage:** See [`examples/all-build-push-image.yml`](examples/all-build-push-image.yml)
104121
* `all-build-push-scan-harbor.yml`
105-
Builds, pushes Docker images to Harbor, and scans with Trivy. Includes auto-detection for push and scan based on git refs and available secrets. Supports SSH for private dependencies.
122+
Builds, pushes Docker images to Harbor, and scans with Trivy. Includes auto-detection for push and scan based on git refs and available secrets. Supports SSH for private dependencies, custom build context and multi-stage targets.
106123
**Usage:** See [`examples/all-build-push-scan-harbor.yml`](examples/all-build-push-scan-harbor.yml)
107124
* `lb-scan.yml`
108125
Scans repository filesystem for security vulnerabilities using Trivy. Requires `pull-requests: write` permission.
@@ -111,6 +128,15 @@ This repository provides a centralized collection of reusable GitHub Actions wor
111128
Builds Docker image, pushes to registry (on tags), and scans with Trivy. Includes optional SSH support for private dependencies.
112129
**Usage:** See [`examples/lb-push-scan-image.yml`](examples/lb-push-scan-image.yml)
113130

131+
### Helm Workflows
132+
133+
* `all-helm-lint.yml`
134+
Lints, templates, and validates Helm charts. Auto-detects chart name and supports custom values files.
135+
**Usage:** See [`examples/all-helm-lint.yml`](examples/all-helm-lint.yml)
136+
* `all-helm-publish.yml`
137+
Packages and publishes Helm charts to Harbor OCI registry. Includes version extraction from tags and GitHub summary with install command.
138+
**Usage:** See [`examples/all-helm-publish.yml`](examples/all-helm-publish.yml)
139+
114140
### Release & Changelog Workflows
115141

116142
* `all-gen-changelog-ai.yml`

examples/all-build-push-scan-harbor.yml

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,23 @@ jobs:
1212
with:
1313
image_name: my-app # (required) Name of the Docker image
1414
organization: my-org # (required) Harbor organization name
15-
registry: harbor.example.com # (required) Docker registry URL
15+
# registry: registry.mconf.com # (optional) Docker registry URL (default: registry.mconf.com)
16+
# context_path: . # (optional) Build context directory (default: .)
1617
# dockerfile_path: './Dockerfile' # (optional) Path to Dockerfile (default: ./Dockerfile)
18+
# build_target: '' # (optional) Docker build target stage for multi-stage builds (default: '')
1719
# platforms: 'linux/amd64' # (optional) Target platforms (default: linux/amd64)
1820
# build-args: | # (optional) Build arguments
1921
# ARG1=value1
2022
# ARG2=value2
2123
# push_enabled: true # (optional) Force enable/disable push (default: auto-detect from tags)
2224
# scan_enabled: true # (optional) Force enable/disable scanning (default: auto-detect from secrets)
23-
secrets:
24-
HARBOR_USERNAME: ${{ secrets.HARBOR_USERNAME }} # (required) Harbor registry username
25-
HARBOR_PASSWORD: ${{ secrets.HARBOR_PASSWORD }} # (required) Harbor registry password
26-
# DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} # (optional) DockerHub username for pulling base images
27-
# DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }} # (optional) DockerHub password
28-
# SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} # (optional) SSH key for private dependencies
29-
# TRIVY_EXPLORER_AUTH_TOKEN: ${{ secrets.TRIVY_EXPLORER_AUTH_TOKEN }} # (optional) Trivy Explorer auth token
30-
# TRIVY_EXPLORER_URL: ${{ secrets.TRIVY_EXPLORER_URL }} # (optional) Trivy Explorer URL
25+
secrets: inherit # Passes all secrets to the reusable workflow
26+
# Or specify secrets explicitly:
27+
# secrets:
28+
# HARBOR_USERNAME: ${{ secrets.HARBOR_USERNAME }} # Harbor registry username
29+
# HARBOR_PASSWORD: ${{ secrets.HARBOR_PASSWORD }} # Harbor registry password
30+
# DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} # (optional) DockerHub username for pulling base images
31+
# DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }} # (optional) DockerHub password
32+
# SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} # (optional) SSH key for private dependencies
33+
# TRIVY_EXPLORER_AUTH_TOKEN: ${{ secrets.TRIVY_EXPLORER_AUTH_TOKEN }} # (optional) Trivy Explorer auth token
34+
# TRIVY_EXPLORER_URL: ${{ secrets.TRIVY_EXPLORER_URL }} # (optional) Trivy Explorer URL

examples/all-helm-lint.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Helm Chart Lint
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'chart/**'
8+
- '.github/workflows/helm-lint.yml'
9+
10+
jobs:
11+
lint:
12+
uses: mconf/mconf-ci-jobs/.github/workflows/all-helm-lint.yml@main
13+
with:
14+
chart_path: chart # (required) Path to Helm chart directory
15+
# helm_version: v3.12.0 # (optional) Helm version to use (default: v3.12.0)
16+
# chart_name: my-app # (optional) Chart name for templating (auto-detected from directory if not provided)
17+
# values_file: chart/values-custom.yaml # (optional) Custom values file for templating validation
18+
# runs-on: '["self-hosted", "ubuntu-22.04"]' # (optional) Runner labels (default: self-hosted ubuntu-22.04)

examples/all-helm-publish.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Helm Chart Publish
2+
3+
on:
4+
push:
5+
tags:
6+
- 'my-app-helm-chart-*' # Tag pattern: {chart_name}-helm-chart-{version}
7+
8+
jobs:
9+
publish:
10+
uses: mconf/mconf-ci-jobs/.github/workflows/all-helm-publish.yml@main
11+
with:
12+
chart_path: chart # (required) Path to Helm chart directory
13+
chart_name: my-app # (required) Chart name (used for version extraction from tag)
14+
organization: my-org # (required) Harbor organization name
15+
# registry: registry.mconf.com # (optional) Harbor registry URL (default: registry.mconf.com)
16+
# chart_repo: helm-charts # (optional) Helm chart repository name in Harbor (default: helm-charts)
17+
# helm_version: v3.12.0 # (optional) Helm version to use (default: v3.12.0)
18+
# tag_prefix: my-app-helm-chart- # (optional) Custom tag prefix for version extraction (default: {chart_name}-helm-chart-)
19+
# runs-on: '["self-hosted", "ubuntu-22.04"]' # (optional) Runner labels (default: self-hosted ubuntu-22.04)
20+
secrets: inherit # Passes all secrets to the reusable workflow
21+
# Or specify secrets explicitly:
22+
# secrets:
23+
# HARBOR_USERNAME: ${{ secrets.HARBOR_USERNAME }} # (required) Harbor registry username
24+
# HARBOR_PASSWORD: ${{ secrets.HARBOR_PASSWORD }} # (required) Harbor registry password

0 commit comments

Comments
 (0)