CI/CD Pipeline(DEV) #7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CI/CD Pipeline(DEV) | |
concurrency: | |
group: ${{ github.ref }} | |
cancel-in-progress: false | |
# on: | |
# push: | |
# branches: | |
# - main | |
on: | |
workflow_dispatch: | |
jobs: | |
build_test_and_push: | |
name: Build, Test, and Deploy | |
runs-on: ubuntu-latest | |
permissions: write-all | |
environment: dev | |
defaults: | |
run: | |
working-directory: ./WebApp | |
steps: | |
# Checkout code | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
# Fetch tags and get the latest version | |
- name: Fetch tags and get the latest version | |
id: version | |
run: | | |
# Fetch all tags to ensure we have access to the latest tag | |
git fetch --tags | |
# Get the latest tag (current version) | |
LATEST_TAG=$(git describe --tags --abbrev=0) | |
echo "Latest tag version: $LATEST_TAG" | |
echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV | |
# Determine the new version based on commit types | |
- name: Determine the new version based on commit types | |
id: versioning | |
run: | | |
# Analyze the last commit message | |
LAST_COMMIT=$(git log -1 --pretty=%B) | |
if [[ "$LAST_COMMIT" =~ feat! ]]; then | |
VERSION_TYPE="major" | |
elif [[ "$LAST_COMMIT" =~ feat ]]; then | |
VERSION_TYPE="minor" | |
elif [[ "$LAST_COMMIT" =~ fix ]]; then | |
VERSION_TYPE="patch" | |
elif [[ "$LAST_COMMIT" =~ chore|docs|ci|perf|refactor|style|test ]]; then | |
VERSION_TYPE="patch" | |
else | |
VERSION_TYPE="patch" # Default to patch if no match | |
fi | |
echo "Determined version bump type: $VERSION_TYPE" | |
# Check commit messages and categorize | |
- name: Check commit messages and categorize | |
id: commit_check | |
run: | | |
patch_commits=() | |
minor_commits=() | |
major_commits=() | |
invalid_commits=() | |
# Get the last commit message from the pull request | |
commit=$(git log -1 --pretty=%s) | |
if [[ "$commit" =~ \(patch\).* ]]; then | |
patch_commits+=("$commit") | |
elif [[ "$commit" =~ \(minor\).* ]]; then | |
minor_commits+=("$commit") | |
elif [[ "$commit" =~ \(major\).* ]]; then | |
major_commits+=("$commit") | |
else | |
minor_commits+=("Invalid Commit Message: $commit") # Treat invalid as minor | |
echo "Warning: Invalid commit message: $commit. Treating as minor." | |
fi | |
echo "patch_commits=$(printf '%s\n' "${patch_commits[@]}")" >> "$GITHUB_OUTPUT" | |
echo "minor_commits=$(printf '%s\n' "${minor_commits[@]}")" >> "$GITHUB_OUTPUT" | |
echo "major_commits=$(printf '%s\n' "${major_commits[@]}")" >> "$GITHUB_OUTPUT" | |
shell: bash | |
# Setup .NET | |
- name: Setup .NET | |
uses: actions/setup-dotnet@v4 | |
with: | |
dotnet-version: '9.0.x' | |
# Install dependencies | |
- name: Install dependencies | |
run: dotnet restore | |
# Build the application | |
- name: Build | |
run: dotnet build --no-restore --configuration Release -nowarn:9999 | |
# Run unit tests | |
- name: Run Unit Tests | |
run: dotnet test --no-build --verbosity normal | |
# Generate Semantic Version | |
- name: Generate Semantic Version | |
id: semver | |
uses: paulhatch/[email protected] | |
with: | |
tag_prefix: "v" | |
version_format: "${major}.${minor}.${patch}" | |
major_pattern: "/^feat!:|^BREAKING CHANGE:/" | |
minor_pattern: "/^feat:|^minor:/" | |
major_regexp_flags: "i" | |
minor_regexp_flags: "i" | |
# Create release | |
- name: Create release | |
uses: softprops/action-gh-release@v2 | |
with: | |
name: ${{ steps.semver.outputs.version_tag }} | |
tag_name: ${{ steps.semver.outputs.version_tag }} | |
fail_on_unmatched_files: true | |
generate_release_notes: true | |
# Setup git config | |
- name: Setup git config | |
env: | |
NEXT_TAG: ${{ steps.semver.outputs.version_tag }} | |
run: | | |
git config user.name 'github-actions[bot]' | |
git config user.email 'github-actions[bot]@users.noreply.github.com' | |
# Configure AWS Credentials | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
role-to-assume: ${{ secrets.AWS_ROLE_ARN_DEV }} | |
aws-region: ${{ secrets.AWS_DEFAULT_REGION }} | |
# Log in to Amazon ECR | |
- name: Log in to Amazon ECR | |
run: | | |
aws ecr get-login-password --region ${{ secrets.AWS_DEFAULT_REGION }} | docker login --username AWS --password-stdin ${{ secrets.ECR_URI_DEV }} | |
# Build Docker Image | |
- name: Build Docker Image | |
run: | | |
docker build -t ${{ secrets.ECR_URI_DEV }}:${{ steps.semver.outputs.version_tag }} . | |
docker build -t ${{ secrets.ECR_URI_DEV }}:latest . | |
# Push Docker Image to ECR | |
- name: Push Docker Image to ECR | |
run: | | |
docker push ${{ secrets.ECR_URI_DEV }}:${{ steps.semver.outputs.version_tag }} | |
docker push ${{ secrets.ECR_URI_DEV }}:latest | |
# Save Docker Image as Artifact | |
- name: Save Docker Image as Artifact | |
env: | |
VERSION: ${{ steps.semver.outputs.version_tag }} | |
ECR_URI_DEV: ${{ secrets.ECR_URI_DEV }} | |
run: | | |
echo "Saving Docker image $ECR_URI_DEV:$VERSION as an artifact" | |
docker save $ECR_URI_DEV:$VERSION | gzip > web-reporting_$VERSION.tar.gz | |
- name: Upload Docker Image Artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: docker-image-${{ steps.semver.outputs.version_tag }} | |
path: ./WebApp/web-reporting_${{ steps.semver.outputs.version_tag }}.tar.gz | |
- name: Download task definition | |
run: | | |
aws ecs describe-task-definition --task-definition nci-oars-dev-taskdefinition --query taskDefinition > task-definition.json | |
- name: Fill in the new image ID in the Amazon ECS task definition | |
id: task-def | |
uses: aws-actions/amazon-ecs-render-task-definition@v1 | |
with: | |
task-definition: ./WebApp/task-definition.json | |
container-name: web | |
image: ${{ secrets.ECR_URI_DEV }}:latest | |
- name: Deploy Amazon ECS task definition | |
uses: aws-actions/amazon-ecs-deploy-task-definition@v2 | |
with: | |
task-definition: ${{ steps.task-def.outputs.task-definition }} | |
service: nci-oars-dev-service | |
cluster: nci-oars-dev-cluster | |
wait-for-service-stability: true | |
- name: Capture Workflow Run ID | |
id: get_run_id | |
uses: actions/github-script@v6 | |
with: | |
script: | | |
const runId = context.runId; | |
core.setOutput('run_id', runId); | |
# Print Version and Run ID in comments | |
- name: Print Version and Run ID | |
run: | | |
echo "Version: ${{ steps.semver.outputs.version_tag }}" | |
echo "Run ID: ${{ steps.get_run_id.outputs.run_id }}" | |
- name: Add Summary | |
if: ${{ always() }} | |
uses: actions/github-script@v6 | |
with: | |
script: | | |
const version = '${{ steps.semver.outputs.version_tag }}'; | |
const runId = '${{ steps.get_run_id.outputs.run_id }}'; | |
core.summary.addHeading("Deployment to DEV").addTable([ | |
[{ data: "Version", header: true }, { data: "Run ID", header: true }], | |
[version, runId], | |
]) | |
await core.summary.write() | |
# Trigger Approval Workflow for Next Environment | |
- name: Trigger Approval for Next Environment | |
if: ${{ always() }} | |
uses: actions/github-script@v6 | |
with: | |
script: | | |
const version = '${{ steps.semver.outputs.version_tag }}'; | |
const runId = '${{ steps.get_run_id.outputs.run_id }}'; | |
console.log(`Version: ${version}, Run ID: ${runId}`); | |
github.rest.actions.createWorkflowDispatch({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
workflow_id: 'qa-push.yaml', | |
ref: 'main', | |
inputs: { | |
version: version, | |
run_id: runId | |
} | |
}); |