Compare commits
3 Commits
v0.0.1
...
sisyphus/c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d35a76669 | ||
|
|
ba74a5c52e | ||
|
|
fce12f7cf0 |
@@ -1,11 +1,23 @@
|
|||||||
name: CD Bootstrap - Release Image Publish
|
name: CD Bootstrap - Release Image Publish
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_run:
|
workflow_dispatch:
|
||||||
workflows: ["CI Pipeline"]
|
inputs:
|
||||||
types: [completed]
|
image_tag:
|
||||||
branches: [main]
|
description: 'Image tag (e.g., v1.0.0, latest, dev)'
|
||||||
workflow_dispatch: # Manual trigger for testing
|
required: true
|
||||||
|
default: 'latest'
|
||||||
|
type: string
|
||||||
|
build_backend:
|
||||||
|
description: 'Build backend image'
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
type: boolean
|
||||||
|
build_frontend:
|
||||||
|
description: 'Build frontend image'
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
type: boolean
|
||||||
|
|
||||||
env:
|
env:
|
||||||
REGISTRY_HOST: 192.168.241.13:8080
|
REGISTRY_HOST: 192.168.241.13:8080
|
||||||
@@ -13,59 +25,58 @@ env:
|
|||||||
FRONTEND_IMAGE: workclub-frontend
|
FRONTEND_IMAGE: workclub-frontend
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
gate:
|
prepare:
|
||||||
name: CI Success & Release Tag Gate
|
name: Prepare Build Metadata
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
is_release_tag: ${{ steps.validate.outputs.is_release_tag }}
|
image_tag: ${{ steps.metadata.outputs.image_tag }}
|
||||||
image_tag: ${{ steps.validate.outputs.image_tag }}
|
image_sha: ${{ steps.metadata.outputs.image_sha }}
|
||||||
image_sha: ${{ steps.validate.outputs.image_sha }}
|
build_backend: ${{ steps.metadata.outputs.build_backend }}
|
||||||
|
build_frontend: ${{ steps.metadata.outputs.build_frontend }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check CI workflow conclusion
|
- name: Generate build metadata
|
||||||
if: ${{ github.event.workflow_run.conclusion != 'success' }}
|
id: metadata
|
||||||
run: |
|
run: |
|
||||||
echo "CI Pipeline did not succeed (conclusion: ${{ github.event.workflow_run.conclusion }})"
|
IMAGE_TAG="${{ github.event.inputs.image_tag }}"
|
||||||
exit 1
|
if [[ -z "$IMAGE_TAG" ]]; then
|
||||||
|
IMAGE_TAG="latest"
|
||||||
- name: Validate release tag and extract version
|
|
||||||
id: validate
|
|
||||||
run: |
|
|
||||||
# Extract ref from workflow_run event or direct trigger
|
|
||||||
REF="${{ github.event.workflow_run.head_branch }}"
|
|
||||||
if [[ -z "$REF" ]]; then
|
|
||||||
REF="${{ github.ref }}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Detected ref: $REF"
|
|
||||||
|
|
||||||
# Check if ref matches release tag pattern (refs/tags/v*)
|
|
||||||
if [[ "$REF" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+ ]] || [[ "$REF" =~ ^v[0-9]+\.[0-9]+\.[0-9]+ ]]; then
|
|
||||||
# Extract version tag (vX.Y.Z)
|
|
||||||
IMAGE_TAG=$(echo "$REF" | sed 's|refs/tags/||')
|
|
||||||
|
|
||||||
# Extract short commit SHA (first 7 chars)
|
|
||||||
IMAGE_SHA="${{ github.event.workflow_run.head_sha }}"
|
|
||||||
if [[ -z "$IMAGE_SHA" ]]; then
|
|
||||||
IMAGE_SHA="${{ github.sha }}"
|
IMAGE_SHA="${{ github.sha }}"
|
||||||
fi
|
|
||||||
IMAGE_SHA_SHORT="${IMAGE_SHA:0:7}"
|
IMAGE_SHA_SHORT="${IMAGE_SHA:0:7}"
|
||||||
|
|
||||||
echo "is_release_tag=true" >> $GITHUB_OUTPUT
|
BUILD_BACKEND="${{ github.event.inputs.build_backend }}"
|
||||||
|
BUILD_FRONTEND="${{ github.event.inputs.build_frontend }}"
|
||||||
|
|
||||||
|
if [[ -z "$BUILD_BACKEND" || "$BUILD_BACKEND" == "false" ]]; then
|
||||||
|
BUILD_BACKEND="false"
|
||||||
|
else
|
||||||
|
BUILD_BACKEND="true"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$BUILD_FRONTEND" || "$BUILD_FRONTEND" == "false" ]]; then
|
||||||
|
BUILD_FRONTEND="false"
|
||||||
|
else
|
||||||
|
BUILD_FRONTEND="true"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
|
echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
|
||||||
echo "image_sha=$IMAGE_SHA_SHORT" >> $GITHUB_OUTPUT
|
echo "image_sha=$IMAGE_SHA_SHORT" >> $GITHUB_OUTPUT
|
||||||
|
echo "build_backend=$BUILD_BACKEND" >> $GITHUB_OUTPUT
|
||||||
|
echo "build_frontend=$BUILD_FRONTEND" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
echo "✅ Release tag detected: $IMAGE_TAG (SHA: $IMAGE_SHA_SHORT)"
|
echo "✅ Build configuration:"
|
||||||
else
|
echo " Image Tag: $IMAGE_TAG"
|
||||||
echo "is_release_tag=false" >> $GITHUB_OUTPUT
|
echo " Commit SHA: $IMAGE_SHA_SHORT"
|
||||||
echo "⏭️ Not a release tag, skipping image publish"
|
echo " Build Backend: $BUILD_BACKEND"
|
||||||
fi
|
echo " Build Frontend: $BUILD_FRONTEND"
|
||||||
|
|
||||||
backend-image:
|
backend-image:
|
||||||
name: Build & Push Backend Image
|
name: Build & Push Backend Image
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [gate]
|
needs: [prepare]
|
||||||
if: needs.gate.outputs.is_release_tag == 'true'
|
if: needs.prepare.outputs.build_backend == 'true'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
@@ -81,20 +92,20 @@ jobs:
|
|||||||
working-directory: ./backend
|
working-directory: ./backend
|
||||||
run: |
|
run: |
|
||||||
docker build \
|
docker build \
|
||||||
-t ${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:${{ needs.gate.outputs.image_tag }} \
|
-t ${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:${{ needs.prepare.outputs.image_tag }} \
|
||||||
-f Dockerfile \
|
-f Dockerfile \
|
||||||
.
|
.
|
||||||
|
|
||||||
- name: Tag with commit SHA
|
- name: Tag with commit SHA
|
||||||
run: |
|
run: |
|
||||||
docker tag \
|
docker tag \
|
||||||
${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:${{ needs.gate.outputs.image_tag }} \
|
${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:${{ needs.prepare.outputs.image_tag }} \
|
||||||
${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:sha-${{ needs.gate.outputs.image_sha }}
|
${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:sha-${{ needs.prepare.outputs.image_sha }}
|
||||||
|
|
||||||
- name: Push images to registry
|
- name: Push images to registry
|
||||||
run: |
|
run: |
|
||||||
docker push ${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:${{ needs.gate.outputs.image_tag }}
|
docker push ${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:${{ needs.prepare.outputs.image_tag }}
|
||||||
docker push ${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:sha-${{ needs.gate.outputs.image_sha }}
|
docker push ${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:sha-${{ needs.prepare.outputs.image_sha }}
|
||||||
|
|
||||||
- name: Capture push evidence
|
- name: Capture push evidence
|
||||||
run: |
|
run: |
|
||||||
@@ -106,8 +117,8 @@ jobs:
|
|||||||
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||||||
"details": {
|
"details": {
|
||||||
"image": "${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}",
|
"image": "${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}",
|
||||||
"version_tag": "${{ needs.gate.outputs.image_tag }}",
|
"version_tag": "${{ needs.prepare.outputs.image_tag }}",
|
||||||
"sha_tag": "sha-${{ needs.gate.outputs.image_sha }}",
|
"sha_tag": "sha-${{ needs.prepare.outputs.image_sha }}",
|
||||||
"registry": "${{ env.REGISTRY_HOST }}"
|
"registry": "${{ env.REGISTRY_HOST }}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,8 +134,8 @@ jobs:
|
|||||||
frontend-image:
|
frontend-image:
|
||||||
name: Build & Push Frontend Image
|
name: Build & Push Frontend Image
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [gate]
|
needs: [prepare]
|
||||||
if: needs.gate.outputs.is_release_tag == 'true'
|
if: needs.prepare.outputs.build_frontend == 'true'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
@@ -140,20 +151,20 @@ jobs:
|
|||||||
working-directory: ./frontend
|
working-directory: ./frontend
|
||||||
run: |
|
run: |
|
||||||
docker build \
|
docker build \
|
||||||
-t ${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:${{ needs.gate.outputs.image_tag }} \
|
-t ${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:${{ needs.prepare.outputs.image_tag }} \
|
||||||
-f Dockerfile \
|
-f Dockerfile \
|
||||||
.
|
.
|
||||||
|
|
||||||
- name: Tag with commit SHA
|
- name: Tag with commit SHA
|
||||||
run: |
|
run: |
|
||||||
docker tag \
|
docker tag \
|
||||||
${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:${{ needs.gate.outputs.image_tag }} \
|
${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:${{ needs.prepare.outputs.image_tag }} \
|
||||||
${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:sha-${{ needs.gate.outputs.image_sha }}
|
${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:sha-${{ needs.prepare.outputs.image_sha }}
|
||||||
|
|
||||||
- name: Push images to registry
|
- name: Push images to registry
|
||||||
run: |
|
run: |
|
||||||
docker push ${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:${{ needs.gate.outputs.image_tag }}
|
docker push ${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:${{ needs.prepare.outputs.image_tag }}
|
||||||
docker push ${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:sha-${{ needs.gate.outputs.image_sha }}
|
docker push ${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:sha-${{ needs.prepare.outputs.image_sha }}
|
||||||
|
|
||||||
- name: Capture push evidence
|
- name: Capture push evidence
|
||||||
run: |
|
run: |
|
||||||
@@ -165,8 +176,8 @@ jobs:
|
|||||||
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||||||
"details": {
|
"details": {
|
||||||
"image": "${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}",
|
"image": "${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}",
|
||||||
"version_tag": "${{ needs.gate.outputs.image_tag }}",
|
"version_tag": "${{ needs.prepare.outputs.image_tag }}",
|
||||||
"sha_tag": "sha-${{ needs.gate.outputs.image_sha }}",
|
"sha_tag": "sha-${{ needs.prepare.outputs.image_sha }}",
|
||||||
"registry": "${{ env.REGISTRY_HOST }}"
|
"registry": "${{ env.REGISTRY_HOST }}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,50 +193,21 @@ jobs:
|
|||||||
release-summary:
|
release-summary:
|
||||||
name: Create Release Summary Evidence
|
name: Create Release Summary Evidence
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [gate, backend-image, frontend-image]
|
needs: [prepare, backend-image, frontend-image]
|
||||||
if: always() && needs.gate.outputs.is_release_tag == 'true'
|
if: always()
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Generate release summary
|
- name: Generate release summary
|
||||||
run: |
|
run: |
|
||||||
mkdir -p .sisyphus/evidence
|
mkdir -p .sisyphus/evidence
|
||||||
|
|
||||||
# Task 30 evidence: CI gate validation
|
|
||||||
cat > .sisyphus/evidence/task-30-ci-gate.json <<EOF
|
|
||||||
{
|
|
||||||
"scenario": "ci_success_gate",
|
|
||||||
"result": "passed",
|
|
||||||
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
||||||
"details": {
|
|
||||||
"ci_workflow": "CI Pipeline",
|
|
||||||
"ci_conclusion": "${{ github.event.workflow_run.conclusion }}",
|
|
||||||
"source_ref": "${{ github.event.workflow_run.head_branch }}",
|
|
||||||
"validated": "true"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Task 30 evidence: Non-tag skip proof (placeholder for documentation)
|
|
||||||
cat > .sisyphus/evidence/task-30-non-tag-skip.json <<EOF
|
|
||||||
{
|
|
||||||
"scenario": "non_release_tag_skip",
|
|
||||||
"result": "not_applicable",
|
|
||||||
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
||||||
"details": {
|
|
||||||
"note": "This workflow only runs on release tags (refs/tags/v*)",
|
|
||||||
"gate_condition": "is_release_tag == true",
|
|
||||||
"current_execution": "release_tag_detected"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Task 33 evidence: CD bootstrap release summary
|
# Task 33 evidence: CD bootstrap release summary
|
||||||
cat > .sisyphus/evidence/task-33-cd-bootstrap-release.json <<EOF
|
cat > .sisyphus/evidence/task-33-cd-bootstrap-release.json <<EOF
|
||||||
{
|
{
|
||||||
"release_tag": "${{ needs.gate.outputs.image_tag }}",
|
"release_tag": "${{ needs.prepare.outputs.image_tag }}",
|
||||||
"commit_sha": "${{ needs.gate.outputs.image_sha }}",
|
"commit_sha": "${{ needs.prepare.outputs.image_sha }}",
|
||||||
"backend_image": "${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:${{ needs.gate.outputs.image_tag }}",
|
"backend_image": "${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:${{ needs.prepare.outputs.image_tag }}",
|
||||||
"frontend_image": "${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:${{ needs.gate.outputs.image_tag }}",
|
"frontend_image": "${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:${{ needs.prepare.outputs.image_tag }}",
|
||||||
"backend_job_conclusion": "${{ needs.backend-image.result }}",
|
"backend_job_conclusion": "${{ needs.backend-image.result }}",
|
||||||
"frontend_job_conclusion": "${{ needs.frontend-image.result }}",
|
"frontend_job_conclusion": "${{ needs.frontend-image.result }}",
|
||||||
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||||
@@ -243,14 +225,14 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo "## 🚀 CD Bootstrap Release Summary" >> $GITHUB_STEP_SUMMARY
|
echo "## 🚀 CD Bootstrap Release Summary" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Release Tag:** ${{ needs.gate.outputs.image_tag }}" >> $GITHUB_STEP_SUMMARY
|
echo "**Release Tag:** ${{ needs.prepare.outputs.image_tag }}" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Commit SHA:** ${{ needs.gate.outputs.image_sha }}" >> $GITHUB_STEP_SUMMARY
|
echo "**Commit SHA:** ${{ needs.prepare.outputs.image_sha }}" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "### Published Images" >> $GITHUB_STEP_SUMMARY
|
echo "### Published Images" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- **Backend:** \`${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:${{ needs.gate.outputs.image_tag }}\`" >> $GITHUB_STEP_SUMMARY
|
echo "- **Backend:** \`${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:${{ needs.prepare.outputs.image_tag }}\`" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- **Backend SHA:** \`${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:sha-${{ needs.gate.outputs.image_sha }}\`" >> $GITHUB_STEP_SUMMARY
|
echo "- **Backend SHA:** \`${{ env.REGISTRY_HOST }}/${{ env.BACKEND_IMAGE }}:sha-${{ needs.prepare.outputs.image_sha }}\`" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- **Frontend:** \`${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:${{ needs.gate.outputs.image_tag }}\`" >> $GITHUB_STEP_SUMMARY
|
echo "- **Frontend:** \`${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:${{ needs.prepare.outputs.image_tag }}\`" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- **Frontend SHA:** \`${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:sha-${{ needs.gate.outputs.image_sha }}\`" >> $GITHUB_STEP_SUMMARY
|
echo "- **Frontend SHA:** \`${{ env.REGISTRY_HOST }}/${{ env.FRONTEND_IMAGE }}:sha-${{ needs.prepare.outputs.image_sha }}\`" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "### Job Results" >> $GITHUB_STEP_SUMMARY
|
echo "### Job Results" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- Backend Image: ${{ needs.backend-image.result }}" >> $GITHUB_STEP_SUMMARY
|
echo "- Backend Image: ${{ needs.backend-image.result }}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|||||||
Reference in New Issue
Block a user