Skip to content
CAMPUX Cloud Bootcamp Lab · CI/CD ← All labs
Hands-On Lab · Beginner
~25 min · $0 · browser only
Azure DevOps · torn down at the end
CI/CD

The pipeline: a file, not a folktale.

Reading an azure-pipelines.yml is not the same as watching one run, fail, and get fixed by your own hand. Here you create a free Azure DevOps organisation, commit a real pipeline with a build stage and a deployment stage, watch it go green — then deliberately break the one line that trips up almost everyone, watch it fail for the reason the class predicted, and fix it.

Fig. 1 · Break the one line that matters
The deployment job's explicit checkout: self is removed, the job fails reading a repo file, and restoring the line fixes it. pipeline file azure-pipelines.yml Build stage implicit checkout — OK Deploy stage deployment job deploy step reads a repo file checkout: self — removed restore it — passes again
● Screen walkthrough Not yet recorded · ~5 min
Reel · 00:00 / 05:00

Victor commits the pipeline, watches it run, removes checkout: self, watches it fail, then fixes it.

Placeholder — the page below stands alone until the reel lands
Why

The gap between reading YAML and owning it

You can read azure-pipelines.yml a dozen times and still not know what happens when a merge fires it, an agent picks it up, and one stage waits on another. This lab closes that gap on the cheapest possible instance of the file: no Azure subscription, no billable resource, nothing but a free Azure DevOps organisation and a browser. You commit the same shape the class taught — a Build stage with an ordinary job, a Deploy stage with a deployment job — watch both go green, then remove the one line the class warned you about and watch the deploy fail for exactly the reason it predicted.

Read it once. Break it once. Then you own it.

Before you begin

You need a Microsoft account (a free outlook.com one works) and a browser — no local installs, no az CLI, no Cloud Shell. Sign up for a free organisation at dev.azure.com if you do not already have one.

Request your free parallel job now — do not skip this

Microsoft now withholds the free Microsoft-hosted parallel job from a brand-new organisation by default, to stop it being used for hidden crypto-mining. Expect to hit this: when you try to run the pipeline in Step 3, the run queues forever and the log reads "No hosted parallelism has been purchased or granted." Handle it before you get there. Go to aka.ms/azpipelines-parallelism-request — the same link Azure DevOps prints inside that error — and submit the request against your new organisation now, while Steps 1 and 2 still give you something to do. Microsoft states a two-to-three business day review, and some requests take longer. The alternative, in Organization settings → Billing, is linking the organisation to a real Azure subscription, which also triggers the grant automatically — but it must be a billable subscription such as Pay-As-You-Go; Azure DevOps does not accept the Azure Free Trial for billing. Either path costs nothing: the grant itself is one Microsoft-hosted job, 1,800 minutes a month, free.

Step 1

A free organisation and project

Everything here happens in the browser, at dev.azure.com.

# in the browser, not a terminal
1. Sign in at https://dev.azure.com with your Microsoft account
2. "Create new organization" > pick a name and a region > Continue
3. "Create a new project" named  campux-warehouse
   - Visibility: Private
   - Version control: Git
   - Work item process: Basic
Checkpoint You land on campux-warehouse's empty Repos page, offering to initialise the repo. Click Initialize with a README so you have a main branch to commit onto.
Step 2

Commit the pipeline, entirely in the browser

Use the Repos web editor — Repos → Files → New → File — to add two files at the repository root. The first is a placeholder "build," so npm run build has something real to do without needing an actual application:

# package.json — at the repo root
{
  "name": "campux-warehouse",
  "version": "1.0.0",
  "scripts": {
    "build": "echo 'warehouse build complete' > dist-marker.txt"
  }
}

The second is the pipeline itself — same shape as the class: a CI trigger, a PR trigger, a Build stage whose ordinary job gets its checkout implicitly, and a Deploy stage whose deployment job does not — so it checks out source explicitly on purpose, then reads a file from that source to prove the checkout mattered:

# azure-pipelines.yml — committed at the repository root
trigger:
  branches:
    include: [ main ]

pr:
  branches:
    include: [ main ]

stages:
  - stage: Build
    jobs:
      - job: build
        pool:
          vmImage: ubuntu-latest
        steps:
          # checkout: self is implicit here — source is already present
          - script: |
              npm run build
            displayName: Build

  - stage: Deploy
    dependsOn: Build
    jobs:
      - deployment: deployWarehouse
        pool:
          vmImage: ubuntu-latest
        environment: warehouse-production
        strategy:
          runOnce:
            deploy:
              steps:
                - checkout: self          # deployment jobs do NOT auto-checkout — this is the line we break
                - script: |
                    echo "Deploying the warehouse build..."
                    cat README.md
                  displayName: Deploy build to the warehouse app
Checkpoint Repos → Files lists both package.json and azure-pipelines.yml at the root, on main.
Why no real Azure deploy here

This lab is about the pipeline mechanics — stages, jobs, the implicit-versus-explicit checkout — not about authenticating to Azure. The deploy step reads a file from the checked-out repo instead of calling az; that is enough to prove whether the source is there. Deploying for real, through a properly scoped service connection, is the next lab.

Step 3

Create the pipeline and watch it run

Point Azure Pipelines at the file you just committed, then watch both stages go green.

# in the browser
1. Pipelines > Create Pipeline
2. "Where is your code?" > Azure Repos Git
3. Select the  campux-warehouse  repository
4. "Configure your pipeline" > Existing Azure Pipelines YAML file
5. Branch: main   Path: /azure-pipelines.yml
6. Review, then "Run"

The first run against a fresh environment name usually pauses once with a banner reading "This pipeline needs permission to access a resource" — select View, then Permit. That click creates the environment; every later run against the same name skips it. If instead the run never starts and stays queued, that is the free-tier grant from the callout above, not this environment step — go request it if you have not already.

Checkpoint Both stages show a green check. Open the Deploy build to the warehouse app step's log: it printed the contents of README.md, proof the explicit checkout: self put the source on the deployment agent.
Step 4

Break it: remove the one line

Now do on purpose what people do by accident. Open azure-pipelines.yml in the Repos web editor, delete the - checkout: self line from the Deploy stage's steps, and commit straight to main. The CI trigger fires the pipeline again automatically.

Checkpoint The Build stage still passes — nothing there changed. The Deploy stage's Deploy build to the warehouse app step fails: cat: README.md: No such file or directory. The deployment job's workspace is empty because a deployment job, unlike an ordinary job, does not clone the repository automatically — the exact behaviour the class flagged as the one people get caught by.
Step 5

Fix it and watch it pass again

Put the line back exactly where it was, first step of the deploy hook, and commit again.

strategy:
  runOnce:
    deploy:
      steps:
        - checkout: self          # restored
        - script: |
            echo "Deploying the warehouse build..."
            cat README.md
          displayName: Deploy build to the warehouse app
Checkpoint The new run's Deploy stage passes again, and the log once more prints README.md. The identical job — same task, same script — went from failing to passing because of one checkout step. That is the entire lesson, watched rather than read.
Down

Tear it down

Nothing here billed you — an idle Azure DevOps organisation, project, and pipeline cost nothing while they sit unused. Tear down anyway; a stray pipeline nobody remembers is exactly the debris a real project accumulates.

# in the browser
1. Pipelines > select the pipeline > ⋯ > Delete
2. Pipelines > Environments > warehouse-production > ⋯ > Delete environment
3. Optional — remove the whole project:
   Organization settings > Projects > campux-warehouse > ⋯ > Delete
4. Optional — remove the whole organisation if you made it just for this lab:
   Organization settings > Overview > Delete
Checkpoint The pipeline no longer appears under Pipelines. If you deleted the project or organisation, its URL now 404s.
End

What you can now honestly claim

You created an Azure DevOps organisation and project from nothing, committed a two-stage azure-pipelines.yml, watched a build job and a deployment job run on separate agents, and proved with your own broken and fixed run — not a paragraph you took on faith — that a deployment job does not check out source automatically. You know what a CI trigger and a PR trigger each answer, why stages hold jobs and jobs hold steps, and the one line that catches almost everyone moving from GitHub Actions. The credential this pipeline is missing on purpose — a real, secret-free connection to Azure, scoped to one resource group — is the next lab.