Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions .github/workflows/_container-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Reusable Container Smoke Test

on:
workflow_call:
inputs:
image-name:
description: Local Docker image tag used for the smoke test.
required: false
type: string
default: thesexy6bot:ci
dockerfile-path:
description: Dockerfile path relative to the repository root.
required: false
type: string
default: Dockerfile
build-context:
description: Docker build context.
required: false
type: string
default: .
git-sha:
description: Commit SHA passed into the image build.
required: true
type: string
commit-message:
description: Commit message passed into the image build.
required: false
type: string
default: ci-smoke
smoke-test-argument:
description: App argument that runs the smoke-test path.
required: false
type: string
default: --smoke-test

jobs:
smoke:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: Checkout app files only
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 1
sparse-checkout: |
Dockerfile
src/dotnet
sparse-checkout-cone-mode: true
persist-credentials: false

- name: Build container image
run: |
short_sha="${GIT_SHA:0:7}"
docker build "$BUILD_CONTEXT" \
--file "$DOCKERFILE_PATH" \
--build-arg GIT_SHA="$short_sha" \
--build-arg GIT_COMMIT_MSG="$COMMIT_MESSAGE" \
-t "$IMAGE_NAME"
env:
BUILD_CONTEXT: ${{ inputs.build-context }}
COMMIT_MESSAGE: ${{ inputs.commit-message }}
DOCKERFILE_PATH: ${{ inputs.dockerfile-path }}
GIT_SHA: ${{ inputs.git-sha }}
IMAGE_NAME: ${{ inputs.image-name }}

- name: Run container smoke test
run: docker run --rm "$IMAGE_NAME" "$SMOKE_TEST_ARGUMENT"
env:
IMAGE_NAME: ${{ inputs.image-name }}
SMOKE_TEST_ARGUMENT: ${{ inputs.smoke-test-argument }}
52 changes: 52 additions & 0 deletions .github/workflows/_dotnet-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Reusable .NET Test

on:
workflow_call:
inputs:
dotnet-version:
description: .NET SDK version to install.
required: false
type: string
default: 9.0.x
solution:
description: Solution file to restore, build, and test.
required: false
type: string
default: TheSexy6BotWorker.slnx
test-filter:
description: Test filter passed to dotnet test.
required: false
type: string
default: Category!=Integration

jobs:
test:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Setup .NET
uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0
with:
dotnet-version: ${{ inputs.dotnet-version }}

- name: Restore dependencies
run: dotnet restore "$SOLUTION"
env:
SOLUTION: ${{ inputs.solution }}

- name: Build
run: dotnet build "$SOLUTION" --no-restore
env:
SOLUTION: ${{ inputs.solution }}

- name: Test
run: dotnet test "$SOLUTION" --no-build --verbosity normal --filter "$TEST_FILTER"
env:
SOLUTION: ${{ inputs.solution }}
TEST_FILTER: ${{ inputs.test-filter }}
113 changes: 113 additions & 0 deletions .github/workflows/_terraform.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
name: Reusable Terraform

on:
workflow_call:
inputs:
apply:
description: Whether to apply the Terraform plan.
required: false
type: boolean
default: false
read-outputs:
description: Whether to expose selected Terraform outputs.
required: false
type: boolean
default: false
github-environment:
description: GitHub environment that provides Terraform vars and Azure secrets.
required: false
type: string
default: stg
terraform-version:
description: Terraform version to install.
required: false
type: string
default: 1.9.8

outputs:
resource_group_name:
description: Terraform resource_group_name output.
value: ${{ jobs.terraform.outputs.resource_group_name }}
container_app_name:
description: Terraform container_app_name output.
value: ${{ jobs.terraform.outputs.container_app_name }}
registry_url:
description: Terraform container_registry_login_server output.
value: ${{ jobs.terraform.outputs.registry_url }}

jobs:
terraform:
permissions:
id-token: write
contents: read
environment: ${{ inputs.github-environment }}
runs-on: ubuntu-latest
env:
ARM_USE_OIDC: true
ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
outputs:
resource_group_name: ${{ steps.tf.outputs.resource_group_name }}
container_app_name: ${{ steps.tf.outputs.container_app_name }}
registry_url: ${{ steps.tf.outputs.registry_url }}
steps:
- name: Checkout Terraform files only
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 1
sparse-checkout: |
src/terraform
sparse-checkout-cone-mode: true
persist-credentials: false

- name: Token replace Terraform env vars
env:
ENVIRONMENT: ${{ vars.ENV_SHORT }}
run: |
sed "s|__ENVIRONMENT__|${ENVIRONMENT}|g" \
src/terraform/environment.tfvars \
> src/terraform/environment.auto.tfvars

- name: Azure Login
uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
enable-AzPSSession: true

- name: Setup Terraform
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd
with:
terraform_version: ${{ inputs.terraform-version }}

- name: Terraform Init
run: |
terraform -chdir=src/terraform init -input=false \
-backend-config="resource_group_name=${VARS_TFSTATE_RESOURCE_GROUP}" \
-backend-config="storage_account_name=${VARS_TFSTATE_STORAGE_ACCOUNT}" \
-backend-config="container_name=${VARS_TFSTATE_CONTAINER}" \
-backend-config="key=${VARS_TFSTATE_KEY}" \
-backend-config="client_id=${AZURE_CLIENT_ID}" \
-backend-config="tenant_id=${AZURE_TENANT_ID}"
env:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
VARS_TFSTATE_RESOURCE_GROUP: ${{ vars.TFSTATE_RESOURCE_GROUP }}
VARS_TFSTATE_STORAGE_ACCOUNT: ${{ vars.TFSTATE_STORAGE_ACCOUNT }}
VARS_TFSTATE_CONTAINER: ${{ vars.TFSTATE_CONTAINER }}
VARS_TFSTATE_KEY: ${{ vars.TFSTATE_KEY }}

- name: Terraform Plan
run: terraform -chdir=src/terraform plan -input=false

- name: Terraform Apply
if: inputs.apply
run: terraform -chdir=src/terraform apply -input=false -auto-approve

- name: Read Terraform outputs
id: tf
if: inputs.read-outputs
run: |
echo "resource_group_name=$(terraform -chdir=src/terraform output -raw resource_group_name)" >> "$GITHUB_OUTPUT"
echo "container_app_name=$(terraform -chdir=src/terraform output -raw container_app_name)" >> "$GITHUB_OUTPUT"
echo "registry_url=$(terraform -chdir=src/terraform output -raw container_registry_login_server)" >> "$GITHUB_OUTPUT"
103 changes: 21 additions & 82 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,111 +27,50 @@ jobs:
terraform:
- 'src/terraform/**'
dotnet:
- 'Dockerfile'
- 'src/dotnet/**'

test-dotnet:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: 'Checkout'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: 'Setup .NET'
uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0
with:
dotnet-version: '9.0.x'

- name: 'Restore dependencies'
run: dotnet restore TheSexy6BotWorker.slnx

- name: 'Build'
run: dotnet build TheSexy6BotWorker.slnx --no-restore

- name: 'Test'
run: dotnet test TheSexy6BotWorker.slnx --no-build --verbosity normal --filter "Category!=Integration"
uses: ./.github/workflows/_dotnet-test.yml

container-smoke:
permissions:
contents: read
needs:
- changes
- test-dotnet
if: needs.changes.outputs.dotnet == 'true' || needs.changes.outputs.terraform == 'true'
uses: ./.github/workflows/_container-smoke.yml
with:
git-sha: ${{ github.sha }}

terraform-plan-apply:
permissions:
id-token: write
contents: read
environment: stg
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.terraform == 'true'
env:
ARM_USE_OIDC: true
ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
steps:
- name: Checkout Terraform files only
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 1
sparse-checkout: |
src/terraform
sparse-checkout-cone-mode: true
persist-credentials: false

- name: Token replace Terraform env vars
env:
ENVIRONMENT: ${{ vars.ENV_SHORT }}
run: |
sed "s|__ENVIRONMENT__|${ENVIRONMENT}|g" \
src/terraform/environment.tfvars \
> src/terraform/environment.auto.tfvars

- name: Azure Login
uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
enable-AzPSSession: true
- name: Setup Terraform
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd
with:
terraform_version: 1.9.8
- name: Terraform Init
run: |
terraform -chdir=src/terraform init -input=false \
-backend-config="resource_group_name=${VARS_TFSTATE_RESOURCE_GROUP}" \
-backend-config="storage_account_name=${VARS_TFSTATE_STORAGE_ACCOUNT}" \
-backend-config="container_name=${VARS_TFSTATE_CONTAINER}" \
-backend-config="key=${VARS_TFSTATE_KEY}" \
-backend-config="client_id=${{ secrets.AZURE_CLIENT_ID }}" \
-backend-config="tenant_id=${{ secrets.AZURE_TENANT_ID }}" \
env:
VARS_TFSTATE_RESOURCE_GROUP: ${{ vars.TFSTATE_RESOURCE_GROUP}}
VARS_TFSTATE_STORAGE_ACCOUNT: ${{ vars.TFSTATE_STORAGE_ACCOUNT}}
VARS_TFSTATE_CONTAINER: ${{ vars.TFSTATE_CONTAINER}}
VARS_TFSTATE_KEY: ${{ vars.TFSTATE_KEY}}

- name: Terraform Plan
run: terraform -chdir=src/terraform plan -input=false

- name: Terraform Apply
run: terraform -chdir=src/terraform apply -input=false -auto-approve

- name: Read Terraform outputs
id: tf
run: |
echo "resource_group_name=$(terraform -chdir=src/terraform output -raw resource_group_name)" >> "$GITHUB_OUTPUT"
echo "container_app_name=$(terraform -chdir=src/terraform output -raw container_app_name)" >> "$GITHUB_OUTPUT"
echo "registry_url=$(terraform -chdir=src/terraform output -raw container_registry_login_server)" >> "$GITHUB_OUTPUT"
uses: ./.github/workflows/_terraform.yml
with:
apply: true
github-environment: stg
read-outputs: true

build-and-deploy-dotnet:
runs-on: ubuntu-latest
needs:
- changes
- test-dotnet
- terraform-plan-apply
- container-smoke
if: >-
${{
always() &&
(needs.changes.outputs.dotnet == 'true' || needs.changes.outputs.terraform == 'true') &&
needs.test-dotnet.result == 'success' &&
needs.container-smoke.result == 'success' &&
(needs.terraform-plan-apply.result == 'success' || needs.terraform-plan-apply.result == 'skipped')
}}
permissions:
Expand All @@ -144,7 +83,7 @@ jobs:
ENVIRONMENT: ${{ vars.ENV_SHORT }}
steps:

- name: Checkout Terraform files only
- name: Checkout app files only
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 1
Expand Down
Loading
Loading