Skip to content

🚀 feat(ci): 優化 CI/CD 流程以支持 Docker 和 NuGet 構建 #325

🚀 feat(ci): 優化 CI/CD 流程以支持 Docker 和 NuGet 構建

🚀 feat(ci): 優化 CI/CD 流程以支持 Docker 和 NuGet 構建 #325

Workflow file for this run

name: Build and Deploy
on:
push:
branches:
- main
- alpha
- beta
- dev
- stg
workflow_dispatch:
inputs:
force:
description: 'Force exec'
type: boolean
required: true
jobs:
Detect:
runs-on: ubuntu-latest
outputs:
docker-matrix: ${{ steps.detect.outputs.docker-matrix }}
nuget-matrix: ${{ steps.detect.outputs.nuget-matrix }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect Change
id: detect
run: |
APP_CORE="Netcorext.Auth.Core"
# Docker 應用程式清單
DOCKER_APPS=(
"Netcorext.Auth.API"
"Netcorext.Auth.Authentication"
"Netcorext.Auth.Authorization"
"Netcorext.Auth.Gateway"
)
# NuGet 套件清單
NUGET_APPS=(
"Netcorext.Auth.Abstractions"
"Netcorext.Auth.Extensions.AspNetCore"
"Netcorext.Auth.Protobufs"
)
# 對 push event,直接用 diff-tree 看當前 commit 的變更
if [ "${{ github.event_name }}" = "push" ]; then
echo "Using git diff-tree for push event"
CHANGE_FILES=$(git diff-tree --no-commit-id --name-only -r HEAD)
else
# workflow_dispatch 或其他 event 用 diff
echo "Using git diff for non-push event"
CHANGE_FILES=$(git diff --name-only HEAD^ HEAD)
fi
echo "Changed files:"
echo "$CHANGE_FILES"
# 建構 Docker 應用程式的 matrix
DOCKER_MATRIX=()
for app in "${DOCKER_APPS[@]}"; do
CHANGED=$(echo "$CHANGE_FILES" | grep -Em 1 "${app}|${APP_CORE}" || true)
if [ -n "$CHANGED" ] || [ "${{ inputs.force }}" = true ]; then
echo "Changes detected in ${app}"
DOCKER_MATRIX+=("{\"app\":\"$app\"}")
else
echo "No changes in ${app}"
fi
done
# 建構 NuGet 套件的 matrix
NUGET_MATRIX=()
for app in "${NUGET_APPS[@]}"; do
CHANGED=$(echo "$CHANGE_FILES" | grep -Em 1 "${app}" || true)
if [ -n "$CHANGED" ] || [ "${{ inputs.force }}" = true ]; then
echo "Changes detected in ${app}"
NUGET_MATRIX+=("{\"app\":\"$app\"}")
else
echo "No changes in ${app}"
fi
done
# 輸出 matrix JSON
if [ ${#DOCKER_MATRIX[@]} -eq 0 ]; then
echo "docker-matrix=[]" >> "$GITHUB_OUTPUT"
else
DOCKER_JSON=$(printf '%s\n' "${DOCKER_MATRIX[@]}" | jq -sc '.')
echo "docker-matrix=$DOCKER_JSON" >> "$GITHUB_OUTPUT"
fi
if [ ${#NUGET_MATRIX[@]} -eq 0 ]; then
echo "nuget-matrix=[]" >> "$GITHUB_OUTPUT"
else
NUGET_JSON=$(printf '%s\n' "${NUGET_MATRIX[@]}" | jq -sc '.')
echo "nuget-matrix=$NUGET_JSON" >> "$GITHUB_OUTPUT"
fi
Build-Docker:
name: "Build ${{ matrix.app }}"
needs: Detect
if: needs.Detect.outputs.docker-matrix != '[]'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.Detect.outputs.docker-matrix) }}
outputs:
tag: ${{ steps.envs.outputs.tag }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: envs
uses: netcorext/dotnet-version-action@dev
with:
app: ${{ matrix.app }}
image-prefix: ${{ vars.IMAGE_PREFIX }}
- uses: netcorext/dotnet-dockerfile-action@dev
with:
expand-command: apt-get update && apt-get install -y curl
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build Image & Push
uses: netcorext/buildx-image-action@dev
with:
image: ${{ steps.envs.outputs.image-fullName }}
tag: ${{ steps.envs.outputs.tag }}
tag-hash: ${{ steps.envs.outputs.tag-hash }}
tag-latest: ${{ steps.envs.outputs.tag-latest }}
build-arg: |-
--build-arg APP="${{ steps.envs.outputs.app }}" \
--build-arg ADDITIONAL_ARGUMENTS="${{ steps.envs.outputs.build-options }}"
Build-NuGet:
name: "Build ${{ matrix.app }}"
needs: Detect
if: needs.Detect.outputs.nuget-matrix != '[]'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.Detect.outputs.nuget-matrix) }}
outputs:
artifact: ${{ steps.build.outputs.artifact }}
steps:
- id: build
name: Build Package
uses: netcorext/dotnet-build-package-action@dev
with:
app: ${{ matrix.app }}
Deploy-NuGet:
name: "Deploy ${{ matrix.app }}"
needs:
- Detect
- Build-NuGet
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.Detect.outputs.nuget-matrix) }}
steps:
- uses: netcorext/push-nuget-package-action@dev
name: Push Package
with:
artifact: ${{ needs.Build-NuGet.outputs.artifact }}
nuget-api-url: ${{ vars.NUGET_API_URL }}
nuget-api-key: ${{ secrets.NUGET_API_KEY }}
Tag:
name: "Tag Version"
needs: Build-Docker
if: needs.Build-Docker.result == 'success' && needs.Build-Docker.outputs.tag != ''
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Create Tag
run: |
VERSION="${{ needs.Build-Docker.outputs.tag }}"
if [ -z "$VERSION" ]; then
echo "No version tag found, skipping"
exit 0
fi
git tag "$VERSION"
git push origin "$VERSION"