Add hard deploy option for Gateway workflow
This commit is contained in:
@@ -4,6 +4,12 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches: [master]
|
branches: [master]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
hard_deploy:
|
||||||
|
description: Always rebuild and deploy both Gateway images
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
type: boolean
|
||||||
|
|
||||||
env:
|
env:
|
||||||
DEPLOY_PATH: /opt/vpn-proxy
|
DEPLOY_PATH: /opt/vpn-proxy
|
||||||
@@ -34,6 +40,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and push gateway image
|
- name: Build and push gateway image
|
||||||
id: gateway-build
|
id: gateway-build
|
||||||
|
env:
|
||||||
|
HARD_DEPLOY_INPUT: ${{ inputs.hard_deploy }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cd repo
|
cd repo
|
||||||
@@ -44,6 +52,11 @@ jobs:
|
|||||||
DATAPLANE_IMAGE="${IMAGE}-dataplane"
|
DATAPLANE_IMAGE="${IMAGE}-dataplane"
|
||||||
|
|
||||||
EVENT_NAME="${{ gitea.event_name }}"
|
EVENT_NAME="${{ gitea.event_name }}"
|
||||||
|
case "${EVENT_NAME}:${HARD_DEPLOY_INPUT}" in
|
||||||
|
workflow_dispatch:true) HARD_DEPLOY=true ;;
|
||||||
|
workflow_dispatch:false|workflow_dispatch:|push:false|push:) HARD_DEPLOY=false ;;
|
||||||
|
*) echo "Invalid hard deploy request: ${EVENT_NAME}:${HARD_DEPLOY_INPUT}" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
BEFORE_SHA="${{ gitea.event.before }}"
|
BEFORE_SHA="${{ gitea.event.before }}"
|
||||||
ZERO_SHA="0000000000000000000000000000000000000000"
|
ZERO_SHA="0000000000000000000000000000000000000000"
|
||||||
if [ "$EVENT_NAME" = "push" ] \
|
if [ "$EVENT_NAME" = "push" ] \
|
||||||
@@ -76,6 +89,13 @@ jobs:
|
|||||||
none:none|control:control|dataplane:both|control+dataplane:both) ;;
|
none:none|control:control|dataplane:both|control+dataplane:both) ;;
|
||||||
*) echo "Invalid runtime impact: ${RUNTIME_IMPACT}" >&2; exit 1 ;;
|
*) echo "Invalid runtime impact: ${RUNTIME_IMPACT}" >&2; exit 1 ;;
|
||||||
esac
|
esac
|
||||||
|
DOCKER_BUILD_OPTIONS=()
|
||||||
|
if [ "$HARD_DEPLOY" = "true" ]; then
|
||||||
|
echo "Hard deploy requested: forcing no-cache rebuild and deploy of both Gateway images."
|
||||||
|
AFFECTED_COMPONENTS="control+dataplane"
|
||||||
|
RESTART_SCOPE="both"
|
||||||
|
DOCKER_BUILD_OPTIONS=(--no-cache)
|
||||||
|
fi
|
||||||
echo "Affected components: ${AFFECTED_COMPONENTS}"
|
echo "Affected components: ${AFFECTED_COMPONENTS}"
|
||||||
echo "Restart scope: ${RESTART_SCOPE}"
|
echo "Restart scope: ${RESTART_SCOPE}"
|
||||||
echo "affected_components=${AFFECTED_COMPONENTS}" >> "$GITHUB_OUTPUT"
|
echo "affected_components=${AFFECTED_COMPONENTS}" >> "$GITHUB_OUTPUT"
|
||||||
@@ -132,6 +152,7 @@ jobs:
|
|||||||
|
|
||||||
echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "$REGISTRY_HOST" -u "${{ gitea.actor }}" --password-stdin
|
echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "$REGISTRY_HOST" -u "${{ gitea.actor }}" --password-stdin
|
||||||
DOCKER_BUILDKIT=1 docker build \
|
DOCKER_BUILDKIT=1 docker build \
|
||||||
|
"${DOCKER_BUILD_OPTIONS[@]}" \
|
||||||
--network host \
|
--network host \
|
||||||
--pull=false \
|
--pull=false \
|
||||||
--build-arg NODE_BUILD_IMAGE="${{ env.NODE_BUILD_IMAGE }}" \
|
--build-arg NODE_BUILD_IMAGE="${{ env.NODE_BUILD_IMAGE }}" \
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
export const HARBOR_VERSIONS = Object.freeze({
|
export const HARBOR_VERSIONS = Object.freeze({
|
||||||
macClient: '0.28.0',
|
macClient: '0.28.0',
|
||||||
gatewayClient: '0.29.0',
|
gatewayClient: '0.29.0',
|
||||||
gatewayBackend: '0.29.0',
|
gatewayBackend: '0.29.1',
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface ParsedVersion {
|
export interface ParsedVersion {
|
||||||
|
|||||||
@@ -33,6 +33,20 @@ test('gateway deploy updates control without recreating dataplane', () => {
|
|||||||
assert.doesNotMatch(workflow, /grep -Eq/);
|
assert.doesNotMatch(workflow, /grep -Eq/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('manual hard deploy safely forces the existing full Gateway path', () => {
|
||||||
|
assert.match(workflow, /workflow_dispatch:\s*\n\s+inputs:\s*\n\s+hard_deploy:[\s\S]*default: false[\s\S]*type: boolean/);
|
||||||
|
assert.match(workflow, /env:\s*\n\s+HARD_DEPLOY_INPUT: \$\{\{ inputs\.hard_deploy \}\}/);
|
||||||
|
assert.match(workflow, /case "\$\{EVENT_NAME\}:\$\{HARD_DEPLOY_INPUT\}" in\s*\n\s+workflow_dispatch:true\) HARD_DEPLOY=true/);
|
||||||
|
assert.match(workflow, /workflow_dispatch:false\|workflow_dispatch:\|push:false\|push:\) HARD_DEPLOY=false/);
|
||||||
|
assert.match(workflow, /\*\) echo "Invalid hard deploy request:[^\n]+exit 1/);
|
||||||
|
assert.match(workflow, /Invalid runtime impact:[\s\S]*DOCKER_BUILD_OPTIONS=\(\)[\s\S]*if \[ "\$HARD_DEPLOY" = "true" \]/);
|
||||||
|
assert.match(workflow, /Hard deploy requested: forcing no-cache rebuild and deploy of both Gateway images\./);
|
||||||
|
assert.match(workflow, /AFFECTED_COMPONENTS="control\+dataplane"\s*\n\s+RESTART_SCOPE="both"\s*\n\s+DOCKER_BUILD_OPTIONS=\(--no-cache\)/);
|
||||||
|
assert.match(workflow, /DOCKER_BUILDKIT=1 docker build \\\n\s+"\$\{DOCKER_BUILD_OPTIONS\[@\]\}"/);
|
||||||
|
assert.match(workflow, /DOCKER_BUILD_OPTIONS=\(--no-cache\)[\s\S]*affected_components=\$\{AFFECTED_COMPONENTS\}[\s\S]*if \[ "\$RESTART_SCOPE" = "none" \]/);
|
||||||
|
assert.equal(workflow.match(/bash scripts\/deploy-gateway\.sh/g)?.length, 1);
|
||||||
|
});
|
||||||
|
|
||||||
test('runtime images contain only compiled application modules', () => {
|
test('runtime images contain only compiled application modules', () => {
|
||||||
for (const dockerfile of dockerfiles) {
|
for (const dockerfile of dockerfiles) {
|
||||||
assert.match(dockerfile, /RUN npm run build:production/);
|
assert.match(dockerfile, /RUN npm run build:production/);
|
||||||
|
|||||||
Reference in New Issue
Block a user