Lab: reusable YAML, agents, and GitHub integration

Outcome

Build an Azure Pipeline from a GitHub training repository, expand a pinned YAML template, run independent jobs in parallel, and diagnose a safe connection or capability failure.

Before you begin

Use a GitHub training repository and an Azure DevOps project. Do not install a self-hosted agent on a workstation that holds credentials or production source. Use Microsoft-hosted agents for the runnable exercise; model self-hosted selection without exposing an internal network.

Learn

GitHub Actions is usually the direct choice for GitHub-native automation; Azure Pipelines is useful when Azure DevOps boards, feeds, environments, or agent-pool controls are the organizational boundary. A Microsoft-hosted Azure Pipelines job receives a fresh VM. A self-hosted agent trades that isolation for control of tools, network reachability, lifecycle, and cache hygiene. Jobs without dependsOn run in parallel when capacity exists; a dependency and condition express the release graph.

Do

  1. Install the Azure Pipelines GitHub App for only the training repository, or create the documented GitHub service connection. In Azure DevOps create a pipeline by choosing that repository and its azure-pipelines.yml.
  2. Add a template repository resource pinned to a tag, not an unreviewed moving branch. Create templates/steps.yml with a message parameter and an echo step.
  3. Create a pipeline with Lint and Unit jobs using ubuntu-latest, both with no dependency. Add Package with dependsOn: [Lint, Unit], then include the pinned template and publish a text artifact containing $(Build.SourceVersion).
  4. Add a variable group with a harmless value such as trainingMessage; authorize only this pipeline. Pass it to the template. Keep secrets out of template parameters and logs.
  5. Add a CleanupEvidence job with condition: failed() that prints only run metadata. Temporarily make Lint exit 1; confirm Package skips and the failure job runs. Restore the lint command.
  6. Add a training-only demand such as TrainingTool. Observe that a Microsoft-hosted agent cannot meet a self-hosted capability demand. Remove the demand for the runnable path. Document what a self-hosted pool would need: patched image, outbound allow-list, one-job isolation, tool inventory, and removal process.

Verify

Capture the GitHub check, Azure Pipelines connection type, expanded template/run log, parallel job graph, artifact with the source SHA, variable-group authorization, and skipped downstream job after the intentional failure. Explain why a template pinned by tag/commit reduces supply-chain drift, but does not authorize its scripts to access a secret.

Break and fix

  1. Revoke the GitHub App/service-connection authorization or remove the repository mapping in the training project. Trigger a run and inspect the connection or webhook error; restore the scoped connection and run again.
  2. Add an impossible agent demand. Distinguish waiting for a busy compatible agent from failure because no agent has the capability, then remove the demand.
  3. Remove dependsOn from Package. Observe that it can run before validation completes; restore the dependency and condition.

Clean up

Delete the training pipeline, service connection or GitHub App installation, variable group, artifacts, and repository. Remove any test self-hosted agent registration and its working directory if you created one.

Scenario practice

  • Configure: Which platform, runner model, and network boundary suit a GitHub repo that deploys to a private internal service?
  • Diagnose: A GitHub push does not start Azure Pipelines. Which evidence distinguishes a YAML/UI trigger override, GitHub App mapping, and OAuth/PAT webhook failure?
  • Distinguish: Why is an Azure Pipelines service connection an authorization boundary, while an agent pool chooses where code executes?

Sources and re-audit

Re-audit when GitHub connection modes, agent images/capabilities, template expansion, or parallel-job entitlement changes.

azure-pipelines · github-actions · service-connection · pipeline-yaml · All labs