Conversation
Create a new ~3-hour workshop section covering CI/CD with GitHub Actions: - Introduction & first CI workflow - Marketplace & caching - Matrix strategies & parallel testing - Deploying to Azure with azd - Creating custom actions - Reusable workflows - Required workflows, branch protection & wrap-up Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add module 0 (setup) for creating repo from template - Rewrite module 1 (intro) as hello world workflow_dispatch - Add module 2 (running tests) with unit + e2e tests in parallel - Add module 3 (caching) for pip/npm with marketplace intro - Update module 4 (matrix) to Python 3.12/3.13/3.14 only - Rewrite module 5 (deploy) to use custom azd pipeline definition - Introduce GITHUB_TOKEN and permissions in module 2 - Replace pytest with unittest across all modules - Update default Python version to 3.14 - Centralize shared setup images to content/images/ - Renumber all modules 0-8 with updated cross-references Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rename the shared images folder to better reflect its cross-workshop purpose. Add screenshots for Dependabot, secret scanning, and code scanning setup. Remove number prefixes from image filenames. Update image paths in all workshop setup files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add new exercise 2 (Securing the Development Pipeline) covering Dependabot, secret scanning, and code scanning. Includes callouts connecting code scanning to GitHub Actions, and a Dependabot note bridging to the CI exercise. Renumber exercises 2-8 to 3-9 and update all cross-references. Additional improvements across all exercises: - Add codespace and terminal callouts at context-switch points - Rename ci.yml to run-tests.yml with display name 'Run Tests' - Rename CD workflow display name to 'Deploy App' - Add 'Open your codespace' section to exercise 0 - Update exercise 3 intro to flow from code scanning module Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The exclude example targets python-version 3.14 on ubuntu-22.04, but the description incorrectly said 3.12. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace staging/production dual-environment pattern with a single deploy workflow gated by branch rulesets. Add manual deploy workflow for rollbacks. This reduces workshop complexity while teaching the same CI/CD concepts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Module 7: Create setup-python-env composite action and update run-tests.yml to use it in both test-api and test-e2e jobs. Module 8: Extract deploy logic into reusable-deploy.yml, update azure-dev.yml to call it, and add manual-deploy.yml for rollbacks. Also update 6-deploy-azure.md with Bicep file descriptions, corrected line reference, azd pipeline config prompts table, and azd show step. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Correct seed_test_database.py to seed_database.py (actual filename) - Add fallback for vars.TEST_DATABASE_PATH in case repo variable isn't set yet Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a new GitHub Actions workshop section and scaffolds Azure Developer CLI (azd) infrastructure + GitHub Actions workflows to support CI (unit + e2e) and CD (deploy to Azure), alongside a few small repo hygiene/content updates.
Changes:
- Add a full “GitHub Actions: From CI to CD” workshop module under
content/github-actions/. - Add GitHub Actions workflows for tests, reusable deployment, and manual deployment, plus a composite action for Python setup + DB seeding.
- Add
azdproject configuration (azure.yaml) and generatedinfra/Bicep/parameter files for Azure Container Apps deployment.
Reviewed changes
Copilot reviewed 28 out of 35 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
server/app.py |
Small change to the Flask server startup line (currently includes an unintended test marker). |
next-steps.md |
Adds post-azd init guidance for provisioning/modifying infra. |
infra/resources.bicep |
Defines Container Apps environment, ACR, client/server apps, identities, and outputs. |
infra/modules/fetch-container-image.bicep |
Helper module to read the existing Container App image metadata. |
infra/main.parameters.json |
Parameter file for Bicep deployment (currently has type issues for booleans). |
infra/main.bicep |
Subscription-scope entrypoint creating RG and invoking resources.bicep. |
infra/abbreviations.json |
Abbreviation map used for resource naming. |
content/shared-images/secret-scanning-settings.png |
Adds a screenshot used in the workshop docs. |
content/github-actions/README.md |
Introduces the GitHub Actions workshop and links exercises. |
content/github-actions/9-required-workflows.md |
Workshop exercise covering rulesets/branch protections/required workflows. |
content/github-actions/8-reusable-workflows.md |
Workshop exercise adding reusable workflows + manual deploy. |
content/github-actions/7-custom-actions.md |
Workshop exercise adding a composite action and reusing it in CI. |
content/github-actions/6-deploy-azure.md |
Workshop exercise for deploying via azd + workflow_run gating. |
content/github-actions/5-matrix-strategies.md |
Workshop exercise adding matrix strategy for Python versions. |
content/github-actions/4-caching.md |
Workshop exercise enabling caching for Python/Node dependencies. |
content/github-actions/3-running-tests.md |
Workshop exercise creating the CI workflow (unit + e2e). |
content/github-actions/2-code-scanning.md |
Workshop exercise enabling security scanning features. |
content/github-actions/1-introduction.md |
Workshop intro exercise and first workflow. |
content/github-actions/0-setup.md |
Workshop setup instructions (template repo + codespaces). |
content/full-day/0-setup.md |
Updates full-day workshop screenshots to shared-images versions. |
content/README.md |
Updates workshop index to include GitHub Actions workshop. |
content/1-hour/0-setup.md |
Updates one-hour workshop screenshots to shared-images versions. |
azure.yaml |
Adds azd service/resource definitions for client/server container apps. |
.gitignore |
Adds .azure and normalizes Playwright report ignore line. |
.github/workflows/run-tests.yml |
Adds CI workflow with Python matrix + Playwright e2e job. |
.github/workflows/reusable-deploy.yml |
Adds reusable deployment workflow using azd up. |
.github/workflows/manual-deploy.yml |
Adds manual deploy workflow calling the reusable deploy workflow. |
.github/workflows/hello.yml |
Adds a basic “Hello World” workflow for workshop intro. |
.github/workflows/azure-dev.yml |
Adds CD workflow gated on CI via workflow_run, calling reusable deploy. |
.github/actions/setup-python-env/action.yml |
Adds composite action to set up Python, install deps, and seed DB (currently has output + DB-path issues). |
Comments suppressed due to low confidence (10)
.github/actions/setup-python-env/action.yml:37
DATABASE_PATHis passed intoseed_database.py, but that script always seedsserver/dogshelter.dbvia a hard-coded SQLite URI, ignoring the env var. This makes thedatabase-pathinput (and the output you set) misleading. Either updateseed_database.py/app DB config to honorDATABASE_PATH, or remove the input/env/output and document that the DB path is fixed.
This issue also appears on line 14 of the same file.
- name: Seed the database
id: seed
run: python server/utils/seed_database.py
shell: bash
env:
DATABASE_PATH: ${{ inputs.database-path }}
.github/workflows/run-tests.yml:35
- This workflow sets
DATABASE_PATHfrom${{ steps.seed.outputs.database-file }}, but the referenced composite action currently doesn't produce that output, so the env var will be empty/undefined. Once the action output is fixed, this becomes reliable; otherwise, consider removing the env var wiring to avoid confusion.
- name: Run tests
run: python -m unittest test_app -v
working-directory: ./server
env:
DATABASE_PATH: ${{ steps.seed.outputs.database-file }}
infra/resources.bicep:202
- The outputs
AZURE_RESOURCE_CLIENT_ID/AZURE_RESOURCE_SERVER_IDcurrently return the Container AppresourceId, not a client ID (appId) for an identity. This is likely to confuse consumers and may break automation expecting an actual clientId. Rename these outputs to reflectresourceId, or change the value to output the intended*.outputs.clientIdfrom the managed identity module.
infra/modules/fetch-container-image.bicep:8 - This module uses a
-previewAPI version forMicrosoft.App/containerApps. Prefer a stable API version for production IaC to reduce the risk of breaking changes and to align with typical Bicep best practices.
content/github-actions/8-reusable-workflows.md:55 - Typo: "pass n" should be "pass in".
For a more controlled approach, you can identify which specific secrets to pass n the reusable workflow's `on.workflow_call.secrets` section:
infra/main.bicep:20
principalIdandprincipalTypeparameters are declared and forwarded toresources.bicep, but they are not used there. Consider removing them end-to-end (main.bicep, main.parameters.json, resources.bicep) unless they are required by some external tooling.
@description('Id of the user or app to assign application roles')
param principalId string
@description('Principal type of user or app')
param principalType string
infra/resources.bicep:15
principalIdandprincipalTypeparameters are declared here but are not used anywhere in this module (role assignments use the managed identity outputs instead). Consider removing these unused params (and the corresponding params inmain.bicep/main.parameters.json) to keep the template minimal and avoid confusion about what identity is being configured.
content/github-actions/7-custom-actions.md:60- The workshop snippet sets the composite action output to
${{ steps.seed.outputs.database-file }}, but the snippet never sets an output on theseedstep (the output is written later via$GITHUB_OUTPUT). This will not work as written for readers following the instructions. Update the snippet to reference the step that writes to$GITHUB_OUTPUT(or set the output from theseedstep).
outputs:
database-file:
description: 'Path to the seeded database file'
value: ${{ steps.seed.outputs.database-file }}
server/app.py:71
- The inline comment has an extra "# test change" appended (and is missing a space before it). This looks like a leftover test edit and should be removed to avoid accidentally committing debug/test markers into production code/comments.
.github/actions/setup-python-env/action.yml:18 - The composite action declares an output
database-fileas${{ steps.seed.outputs.database-file }}, but theseedstep doesn't set any outputs. As written, callers will receive an empty/undefined output. Update the output to reference the step that writes to$GITHUB_OUTPUT(or write the output from theseedstep).
outputs:
database-file:
description: 'Path to the seeded database file'
value: ${{ steps.seed.outputs.database-file }}
| "clientExists": { | ||
| "value": "${SERVICE_CLIENT_RESOURCE_EXISTS=false}" | ||
| }, | ||
| "serverExists": { | ||
| "value": "${SERVICE_SERVER_RESOURCE_EXISTS=false}" | ||
| }, |
There was a problem hiding this comment.
clientExists/serverExists are bool parameters in main.bicep, but in this parameters file they are provided as quoted strings (e.g. "${SERVICE_CLIENT_RESOURCE_EXISTS=false}"). ARM/Bicep parameter values for booleans must be JSON booleans (true/false), not strings, or deployment will fail type validation. Update this file to emit booleans (e.g., remove quotes and ensure substitution produces true/false).
No description provided.