-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaction.yml
More file actions
167 lines (143 loc) · 7.15 KB
/
action.yml
File metadata and controls
167 lines (143 loc) · 7.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
name: 'Kubernetes Helm Multi-Deploy (No Docker)'
description: "Deploys helm charts in a 'deployment' folder. Pass helm-chart-name for a single chart, otherwise deploys all."
icon: play
color: green
inputs:
image-tag:
description: "The image tag to use in the deployments."
required: true
k8s-namespace:
description: "Deployment namespace in kubernetes."
required: true
environment-slug:
description: "Short name of deployment environment. Should be like 'dev', 'prod'. Set this if you have a values-<env>.yaml."
required: false
helm-extra-args:
description: "Add additional/custom helm arguments/commands."
required: false
helm-chart-name:
description: "Deploy a single specific chart by name instead of all charts in the deployment folder."
required: false
helm-chart-name-prefix:
description: "Add string to prefix helm chart name (eg: dev-)"
required: false
helm-chart-name-suffix:
description: "Add string to suffix helm chart name (eg: -dev)"
required: false
dry-run:
description: "Skip the actual deployment and just show a diff."
required: false
default: false
timeout:
description: "The timeout time for helm operations."
required: false
default: 300s
wait:
description: "Wait for deployment to complete and be healthy before returning (uses helm --wait option)."
required: false
default: false
runs:
using: 'composite'
steps:
- shell: bash
run: |
(kubectl --help &> /dev/null && helm diff version &> /dev/null) || (echo "Please install kubectl, helm, and helm-diff in your runner. Alternatively use one of our docker-based versions of this action: https://github.com/DevOps-Nirvana/" && exit 1)
HELM_IMAGE_TAG=${{ inputs.image-tag }}
HELM_K8S_NAMESPACE=${{ inputs.k8s-namespace }}
HELM_ENVIRONMENT_SLUG=${{ inputs.environment-slug }}
HELM_DRY_RUN=${{ inputs.dry-run }}
HELM_EXTRA_ARGS=${{ inputs.helm-extra-args }}
HELM_TIMEOUT=${{ inputs.timeout }}
HELM_CHART_NAME_PREFIX=${{ inputs.helm-chart-name-prefix }}
HELM_CHART_NAME_SUFFIX=${{ inputs.helm-chart-name-suffix }}
HELM_WAIT=""
if [ "${{ inputs.wait }}" = "true" ]; then
HELM_WAIT="--wait"
fi
cd deployment
# Creating namespace if necessary
kubectl create namespace $HELM_K8S_NAMESPACE || true
# Setup our helm args
export HELM_EXTRA_ARGS="$HELM_EXTRA_ARGS --set image.tag=$HELM_IMAGE_TAG --set global.image.tag=$HELM_IMAGE_TAG --set global.namespace=$HELM_K8S_NAMESPACE";
# If a specific chart name was provided, use that; otherwise iterate all
if [ -n "${{ inputs.helm-chart-name }}" ]; then
HELM_CHARTS="${{ inputs.helm-chart-name }}"
else
HELM_CHARTS=$(ls -d */ | grep -Evi "helm_value_files|templates" | tr '/' ' ')
fi
# Iterate through all our deployments
for CURRENT_HELM_CHART in $HELM_CHARTS; do
echo "Update our helm chart dependencies"
helm dependency update $CURRENT_HELM_CHART || true
# Discover values files
VALUES_ENV_FILE=`find $CURRENT_HELM_CHART -name values-${HELM_ENVIRONMENT_SLUG}.yaml`
VALUES_FILE_ARGS="-f $CURRENT_HELM_CHART/values.yaml${VALUES_ENV_FILE:+ -f $VALUES_ENV_FILE}"
echo "--- HELM DIFF ---"
helm diff upgrade --allow-unreleased --namespace $HELM_K8S_NAMESPACE $HELM_UPDIFF_EXTRA_ARGS $HELM_CHART_NAME_PREFIX$CURRENT_HELM_CHART$HELM_CHART_NAME_SUFFIX ./$CURRENT_HELM_CHART \
$VALUES_FILE_ARGS \
$HELM_EXTRA_ARGS
if [ "$HELM_DRY_RUN" = "false" ]; then
echo "--- HELM UPGRADE ---"
helm upgrade --install --atomic --timeout $HELM_TIMEOUT $HELM_WAIT --namespace $HELM_K8S_NAMESPACE $HELM_CHART_NAME_PREFIX$CURRENT_HELM_CHART$HELM_CHART_NAME_SUFFIX ./$CURRENT_HELM_CHART \
$VALUES_FILE_ARGS \
$HELM_EXTRA_ARGS;
fi
done
# Cleanup step that runs when the action is cancelled
- shell: bash
if: cancelled()
run: |
echo "Action was cancelled - checking for pending/broken deployments to rollback..."
HELM_K8S_NAMESPACE=${{ inputs.k8s-namespace }}
HELM_CHART_NAME_PREFIX=${{ inputs.helm-chart-name-prefix }}
HELM_CHART_NAME_SUFFIX=${{ inputs.helm-chart-name-suffix }}
HELM_DRY_RUN=${{ inputs.dry-run }}
HELM_TIMEOUT=${{ inputs.timeout }}
HELM_WAIT=""
if [ "${{ inputs.wait }}" = "true" ]; then
HELM_WAIT="--wait"
fi
# Skip rollback check if this was a dry-run
if [ "$HELM_DRY_RUN" = "true" ]; then
echo "Dry-run mode was enabled, no rollback needed."
exit 0
fi
cd deployment
# If a specific chart name was provided, use that; otherwise iterate all
if [ -n "${{ inputs.helm-chart-name }}" ]; then
HELM_CHARTS="${{ inputs.helm-chart-name }}"
else
HELM_CHARTS=$(ls -d */ | grep -Evi "helm_value_files|templates" | tr '/' ' ')
fi
# Iterate through all our deployments and check their status
for CURRENT_HELM_CHART in $HELM_CHARTS; do
RELEASE_NAME="$HELM_CHART_NAME_PREFIX$CURRENT_HELM_CHART$HELM_CHART_NAME_SUFFIX"
echo "Checking status of release: $RELEASE_NAME"
# Get the release status
RELEASE_STATUS=$(helm status "$RELEASE_NAME" --namespace "$HELM_K8S_NAMESPACE" -o json 2>/dev/null | jq -r '.info.status' 2>/dev/null || echo "not-found")
echo "Release '$RELEASE_NAME' status: $RELEASE_STATUS"
case "$RELEASE_STATUS" in
deployed)
echo "Release '$RELEASE_NAME' is in a healthy state (deployed). No rollback needed."
;;
pending-install|pending-upgrade|pending-rollback|failed|superseded)
echo "Release '$RELEASE_NAME' is in a broken/pending state ($RELEASE_STATUS). Initiating rollback..."
# Get the last successful revision (if any)
LAST_REVISION=$(helm history "$RELEASE_NAME" --namespace "$HELM_K8S_NAMESPACE" -o json 2>/dev/null | jq -r '[.[] | select(.status == "deployed")] | last | .revision // empty' 2>/dev/null || echo "")
if [ -n "$LAST_REVISION" ] && [ "$LAST_REVISION" != "null" ]; then
echo "Rolling back '$RELEASE_NAME' to revision $LAST_REVISION..."
helm rollback "$RELEASE_NAME" "$LAST_REVISION" --namespace "$HELM_K8S_NAMESPACE" --timeout $HELM_TIMEOUT $HELM_WAIT || echo "Rollback failed for $RELEASE_NAME"
else
echo "No previous successful revision found for '$RELEASE_NAME'. Uninstalling the failed release..."
helm uninstall "$RELEASE_NAME" --namespace "$HELM_K8S_NAMESPACE" --timeout $HELM_TIMEOUT $HELM_WAIT || echo "Uninstall failed for $RELEASE_NAME"
fi
;;
not-found)
echo "Release '$RELEASE_NAME' not found. Nothing to rollback."
;;
*)
echo "Release '$RELEASE_NAME' has unknown status: $RELEASE_STATUS. Skipping."
;;
esac
done
echo "Cancellation cleanup complete."