Skip to content

Commit e9406ef

Browse files
committed
chore: refactor
1 parent fbd9731 commit e9406ef

File tree

1 file changed

+25
-122
lines changed

1 file changed

+25
-122
lines changed

.github/workflows/chart-release.yml

Lines changed: 25 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ on:
1010
jobs:
1111
helm-release:
1212
runs-on: ubuntu-latest
13+
env:
14+
GPG_KEY_ID: ${{ secrets.HELM_GPG_KEY_ID }}
15+
GPG_PASSPHRASE: ${{ secrets.HELM_GPG_PASSPHRASE }}
1316

1417
steps:
1518
- name: Checkout
@@ -21,153 +24,53 @@ jobs:
2124
run: |
2225
git config user.name "$GITHUB_ACTOR"
2326
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
24-
helm repo add bitnami https://charts.bitnami.com/bitnami
2527
26-
- name: Import GPG private key and setup keyring
28+
- name: Configure GPG
2729
run: |
28-
# Import GPG key directly from secret (no intermediate files)
29-
echo "Importing GPG key directly from secret..."
30-
31-
# Setup GPG environment for non-interactive use
32-
export GPG_TTY=$(tty)
3330
mkdir -p ~/.gnupg
3431
chmod 700 ~/.gnupg
35-
36-
# Configure GPG for CI/batch mode
3732
echo "pinentry-mode loopback" > ~/.gnupg/gpg.conf
38-
echo "trust-model always" >> ~/.gnupg/gpg.conf
39-
echo "batch" >> ~/.gnupg/gpg.conf
40-
echo "no-tty" >> ~/.gnupg/gpg.conf
41-
42-
echo "allow-loopback-pinentry" > ~/.gnupg/gpg-agent.conf
43-
chmod 600 ~/.gnupg/gpg-agent.conf ~/.gnupg/gpg.conf
44-
45-
# Decode and import in one step (suppress base64 warnings)
46-
echo "${{ secrets.HELM_GPG_PRIVATE_KEY }}" | base64 -d 2>/dev/null | gpg --batch --import
47-
48-
# Create legacy format keyrings that Helm expects
49-
gpg --batch --export > ~/.gnupg/pubring.gpg
50-
51-
# Export secret keys with passphrase (using gpg-preset-passphrase or temp file)
52-
echo "${{ secrets.HELM_GPG_PASSPHRASE }}" | gpg --batch --yes --pinentry-mode loopback --passphrase-fd 0 --export-secret-keys > ~/.gnupg/secring.gpg
53-
54-
# Verify key import (trust-model always is set in gpg.conf, so no ownertrust needed)
55-
echo "Imported GPG keys:"
56-
gpg --list-secret-keys --keyid-format LONG
57-
58-
# Check key algorithm type for Helm compatibility
59-
echo "Key algorithm details:"
60-
gpg --list-secret-keys --with-subkey-fingerprint --keyid-format LONG
61-
62-
# Verify we can use the key for signing
63-
GPG_KEY_ID="${{ secrets.HELM_GPG_KEY_ID }}"
64-
echo "${{ secrets.HELM_GPG_KEY_ID }}"
65-
echo "Key ID to use for signing: $GPG_KEY_ID"
66-
67-
- name: Create GPG passphrase file
68-
run: |
69-
# Create passphrase file directly from secret
70-
echo "${{ secrets.HELM_GPG_PASSPHRASE }}" > gpg-passphrase.txt
71-
chmod 600 gpg-passphrase.txt
33+
echo "${{ secrets.HELM_GPG_PRIVATE_KEY }}" | base64 -d | gpg --batch --import
34+
echo "$GPG_PASSPHRASE" | gpg --batch --passphrase-fd 0 --export-secret-keys > ~/.gnupg/secring.gpg
7235
73-
- name: Package and sign charts using Helm directly
36+
- name: Package and Sign Charts
7437
run: |
75-
# Get the GPG key ID directly from secret for signing
76-
GPG_KEY_ID="${{ secrets.HELM_GPG_KEY_ID }}"
77-
echo "Using GPG key ID: $GPG_KEY_ID"
78-
79-
# Find all charts to package and sign
8038
for chart_dir in charts/*/; do
81-
if [ -f "$chart_dir/Chart.yaml" ]; then
82-
echo "Packaging chart: $chart_dir"
83-
84-
# Package chart without signing first (since Ed25519 not supported by helm)
85-
helm package "$chart_dir"
86-
87-
# Get the generated chart file name
88-
CHART_NAME=$(basename "$chart_dir")
89-
CHART_VERSION=$(helm show chart "$chart_dir" | grep '^version:' | awk '{print $2}')
90-
CHART_FILE="${CHART_NAME}-${CHART_VERSION}.tgz"
91-
92-
echo "Signing chart package: $CHART_FILE"
93-
94-
# Sign the chart package manually with GPG (supports Ed25519)
95-
echo "${{ secrets.HELM_GPG_PASSPHRASE }}" | gpg --batch --yes --pinentry-mode loopback \
96-
--passphrase-fd 0 --local-user "$GPG_KEY_ID" \
97-
--detach-sign --armor "$CHART_FILE"
98-
99-
# Create .prov file (Helm provenance format)
100-
mv "${CHART_FILE}.asc" "${CHART_FILE}.prov"
101-
102-
echo "✅ Successfully signed: $CHART_FILE -> ${CHART_FILE}.prov"
103-
fi
39+
[ -f "$chart_dir/Chart.yaml" ] || continue
40+
helm package "$chart_dir"
41+
CHART_FILE=$(ls -t *.tgz | head -n 1)
42+
echo "$GPG_PASSPHRASE" | gpg --batch --yes --pinentry-mode loopback \
43+
--passphrase-fd 0 --local-user "$GPG_KEY_ID" \
44+
--detach-sign --armor "$CHART_FILE"
45+
mv "${CHART_FILE}.asc" "${CHART_FILE}.prov"
10446
done
105-
106-
# List generated files
107-
echo "Generated files:"
108-
ls -la *.tgz *.prov 2>/dev/null || echo "No chart files found"
10947
110-
- name: Validate signed charts (PR only)
48+
- name: Validate Signed Charts (PR only)
11149
if: github.event_name == 'pull_request'
11250
run: |
113-
echo "🔍 Validating signed charts for PR..."
114-
115-
# Check that both .tgz and .prov files exist
116-
TGZ_COUNT=$(ls *.tgz 2>/dev/null | wc -l)
117-
PROV_COUNT=$(ls *.prov 2>/dev/null | wc -l)
118-
119-
echo "Found $TGZ_COUNT chart packages and $PROV_COUNT signature files"
120-
121-
if [ "$TGZ_COUNT" -eq "$PROV_COUNT" ] && [ "$TGZ_COUNT" -gt 0 ]; then
122-
echo "✅ Chart signing validation successful!"
123-
echo "📦 Chart packages: $(ls *.tgz)"
124-
echo "🔐 Signature files: $(ls *.prov)"
125-
else
51+
[ $(ls *.tgz 2>/dev/null | wc -l) -eq $(ls *.prov 2>/dev/null | wc -l) ] || {
12652
echo "❌ Chart signing validation failed!"
127-
echo "Expected equal number of .tgz and .prov files"
12853
exit 1
129-
fi
54+
}
55+
echo "✅ All charts signed correctly"
13056
131-
- name: Create GitHub Release with signed charts
57+
- name: Create Release (Manual trigger only)
13258
if: github.event_name == 'workflow_dispatch'
13359
run: |
134-
# Get chart version
13560
CHART_VERSION=$(helm show chart charts/exivity/ | grep '^version:' | awk '{print $2}')
13661
RELEASE_TAG="exivity-$CHART_VERSION"
13762
138-
echo "Creating release: $RELEASE_TAG"
63+
gpg --export --armor "$GPG_KEY_ID" > signing-key.asc
13964
140-
# Create release using GitHub CLI
14165
gh release create "$RELEASE_TAG" \
14266
--title "Exivity Helm Chart $CHART_VERSION" \
143-
--notes "Signed Helm chart release for Exivity $CHART_VERSION" \
144-
*.tgz *.prov
145-
env:
146-
GH_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
147-
148-
- name: Export and upload public key
149-
if: github.event_name == 'workflow_dispatch'
150-
run: |
151-
# Export public key using the key ID directly
152-
GPG_KEY_ID="${{ secrets.HELM_GPG_KEY_ID }}"
153-
echo "Exporting public key for key ID: $GPG_KEY_ID"
154-
155-
# Export public key
156-
gpg --batch --export --armor "$GPG_KEY_ID" > exivity-charts-signing-key.asc
157-
158-
# Add to the same release
159-
CHART_VERSION=$(helm show chart charts/exivity/ | grep '^version:' | awk '{print $2}')
160-
RELEASE_TAG="exivity-$CHART_VERSION"
161-
162-
gh release upload "$RELEASE_TAG" exivity-charts-signing-key.asc
67+
--notes "Signed Helm chart release" \
68+
*.tgz *.prov signing-key.asc
16369
env:
16470
GH_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
16571

166-
- name: Clean up sensitive files
72+
- name: Cleanup
16773
if: always()
16874
run: |
169-
rm -f gpg-passphrase.txt
170-
rm -f ~/.gnupg/secring.gpg
171-
# Clear GPG keyring
172-
gpg --batch --yes --delete-secret-keys "${{ secrets.HELM_GPG_KEY_ID }}" 2>/dev/null || true
173-
gpg --batch --yes --delete-keys "${{ secrets.HELM_GPG_KEY_ID }}" 2>/dev/null || true
75+
gpg --batch --yes --delete-secret-keys "$GPG_KEY_ID" 2>/dev/null || true
76+
gpg --batch --yes --delete-keys "$GPG_KEY_ID" 2>/dev/null || true

0 commit comments

Comments
 (0)