AI-Assisted CI/CD Status Page

Build a status page with AI-assisted CI checks and GitHub Pages deployment.

Introduction

30 Second Summary

When an online service has problems, its status page is where people look for a clear answer. A page that looks healthy can still hide a defect that makes the next release unsafe.

In this project, you will build a responsive status dashboard for Northstar with a GitHub Actions pipeline. GitHub Copilot will help you repair a deliberate failure before GitHub Pages publishes the validated site.

What You'll Build

Your repaired commit clears its quality gate before the live Northstar dashboard updates at a public URL.

By the end of this project, you'll have:

  • A responsive Northstar dashboard that shows the Website, API, and Dashboard as operational on desktop or mobile.
  • An AI-assisted CI/CD repair loop that turns a failing workflow log into the smallest safe HTML fix without weakening the quality gate.
  • A public status URL that deploys a new version only after validation succeeds.
  • Secret Mission: Support a degraded service state with an API incident notice and a matching quality gate.

Are there any prerequisites?

You need a Windows computer with internet access. Apart from an existing GitHub account and Visual Studio Code installation, every setup is included.

Before We Start

Take a moment to commit to the public status page you are about to build. Naming why AI-assisted CI/CD matters to you gives every workflow result a clear purpose.

Set Up Your Free AI DevOps Workspace

Your public status page needs a reliable path from Visual Studio Code to GitHub. Git for Windows gives each change a traceable commit.

GitHub Copilot helps you interpret CI/CD results once the pipeline runs. Preparing these tools now gives you a complete path from local work to AI-assisted diagnosis.

In this step, get ready to:
  • Confirm your existing GitHub account and Visual Studio Code installation.
  • Install Git for Windows and configure your commit identity.
  • Enable Copilot Free and test Copilot Chat in Ask mode.
Confirm your GitHub and Visual Studio Code access

The workflow crosses Microsoft Edge and your editor. Confirming both tools now prevents account access from interrupting your first commit.

  • Press the Windows key to open the search bar.
  • Type Microsoft Edge and press Enter to open it.
  • Visit https://github.com.
  • Confirm your existing GitHub account is signed in.
  • Press the Windows key to open the search bar.
  • Type Visual Studio Code and press Enter to open it.
  • Click Help in the Visual Studio Code menu bar.
  • Click About.

What should I see?

GitHub should show your signed-in account instead of asking you to authenticate. The Visual Studio Code About dialog should show the installed editor version.

  • Close the About dialog to return to Visual Studio Code.
Install Git for Windows and set your identity

The git command connects the files on your computer to the repository history you publish later. Start with a version check so you can follow the path that matches your computer.

  • Click Terminal in the Visual Studio Code menu bar.
  • Click New Terminal.
  • Check your installed Git version by running this command:
git --version

What does this command do?

The command asks Git to print its installed version. A version response proves that Visual Studio Code can find the Git client.

✔️ I see the required Git version

Your output identifies Git for Windows 2.56.0(3). Your terminal can use the required Git client.

ⓧ I see an older version

Your terminal found Git, but the installed build is older than 2.56.0(3). Install the required build before configuring your identity.

  • Download the x64 installer for Git for Windows 2.56.0(3) from the official Git for Windows installer page.
  • Close Visual Studio Code.
  • Run the downloaded installer.
  • Keep the default selections until the installation completes.

Why restart Visual Studio Code?

Visual Studio Code needs a fresh session to detect the newly installed Git command. Restarting keeps the next version check tied to the updated installation.

  • Press the Windows key to open the search bar.
  • Type Visual Studio Code and press Enter to reopen it.
  • Click Terminal in the menu bar.
  • Click New Terminal.
  • Verify the updated Git installation by running this command:
git --version

What confirms the upgrade?

The terminal should now identify Git for Windows 2.56.0(3). This confirms that Visual Studio Code is using the updated installation.

Still seeing the older version?

Close every Visual Studio Code window before reopening the editor. A window left running can keep the older command path active.

Help me fix Visual Studio Code detecting an older Git for Windows installation.

ⓧ Command not found

Your terminal cannot find a Git installation. Install Git for Windows before continuing.

  • Download the x64 installer for Git for Windows 2.56.0(3) from the official Git for Windows installer page.
  • Close Visual Studio Code.
  • Run the downloaded installer.
  • Keep the default selections until the installation completes.

Why restart Visual Studio Code?

Visual Studio Code reads the available command paths when it starts. A fresh session lets the integrated terminal find the new Git installation.

  • Press the Windows key to open the search bar.
  • Type Visual Studio Code and press Enter to reopen it.
  • Click Terminal in the menu bar.
  • Click New Terminal.
  • Verify the new Git installation by running this command:
git --version

What confirms the installation?

The terminal should now identify Git for Windows 2.56.0(3). A version response proves the command is available inside Visual Studio Code.

Git still unavailable?

Confirm that the installer finished before reopening Visual Studio Code. Close every editor window if the terminal still cannot find Git.

Help me fix Git not being found in the Visual Studio Code terminal.

Git uses an author name and email to label each commit. These global values become the default identity for repositories on this Windows account.

  • Replace <your-name> with the author name you want attached to your commits.
  • Replace <your-email> with the email you want attached to your commits.
  • Configure both global identity values by running the edited commands:
git config --global user.name "<your-name>"
git config --global user.email "<your-email>"

What do these commands configure?

  • The user.name setting stores the author name shown on future commits.
  • The user.email setting stores the author email shown on future commits.
  • The --global flag applies these defaults to repositories used by your Windows account.

The terminal should return to the prompt without an error. That is your local commit identity sorted.

Having trouble configuring Git?

Make sure both angle-bracket placeholders were replaced before you ran the commands. Keep the quotation marks around names or email addresses that contain spaces.

Help me configure my global Git author identity in the Visual Studio Code terminal.

Enable Copilot Free and test Ask mode

Copilot Chat turns a workflow message into an explanation you can act on. Eligible individual accounts without an existing subscription can enroll in Copilot Free by signing in through Visual Studio Code.

  • Click the Copilot menu in the Visual Studio Code Status Bar.
  • Select Use AI Features.
  • Complete the GitHub sign-in flow in Microsoft Edge if prompted.
  • Return to Visual Studio Code after the authorization completes.

What does Copilot Free include?

Copilot Free provides eligible individual accounts with a limited monthly allowance for AI features. This project uses only a small number of chat prompts.

  • Click the chat icon in the Visual Studio Code title bar.
  • Select Ask from the agents dropdown.

Before you submit the verification prompt, what kind of response would prove Ask mode is answering the question you gave it?

  • Submit the verification question in Copilot Chat by using this prompt:
What do CI and CD each mean in one sentence?

What does this prompt check?

The prompt asks Copilot Chat for a concise explanation of both parts of CI/CD. A relevant response confirms that Ask mode can receive your question and return guidance.

You should see one sentence explaining CI and one sentence explaining CD. Git and Copilot Chat are now both responding inside Visual Studio Code.

Copilot controls missing or sign-in blocked?

Confirm that the GitHub account in Microsoft Edge is the same individual account you want to use in Visual Studio Code. Copilot Free is unavailable to managed user accounts.

Help me enable Copilot Free and open Copilot Chat in Ask mode in Visual Studio Code.

Your workspace is ready for the full DevOps loop. Next, you will build the Northstar page that the pipeline protects.

Build and Publish the Status Page

Your Git client now works inside Visual Studio Code. GitHub Copilot is ready to support you when the pipeline needs diagnosis.

A visible page gives your CI/CD pipeline something real to protect before you publish it to GitHub. The page will report healthy services while deliberately omitting the machine-readable state that the next step checks.

In this step, get ready to:
  • Build a responsive Northstar status dashboard with HTML and CSS.
  • Inspect the operational dashboard locally in Microsoft Edge.
  • Commit the dashboard to a public GitHub repository.
Create the status page files

The HTML defines the dashboard content. The CSS turns that content into a responsive status card.

  • Select the File menu in Visual Studio Code.
  • Choose the command for opening a folder.
  • Select your Desktop in the Windows folder picker.
  • Create a folder named ai-cicd-status-page.
  • Select the new ai-cicd-status-page folder.
  • Confirm the folder selection.

You should see ai-cicd-status-page at the top of the Explorer sidebar. This folder becomes your local repository later in the step.

How Is the Project Organised?

The docs folder holds the static files for the status page. GitHub Pages will deploy this folder later in the project.

  • Create a folder named docs from the Explorer sidebar.
  • Create index.html inside the docs folder.

You should see docs/index.html in the Explorer sidebar. The first code chunk gives the browser a valid document shell.

  • Build the document shell in docs/index.html by pasting this code:
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Northstar service status dashboard">
  <title>Northstar Status</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="status-shell">
  </main>
</body>
</html>

What Does the Document Shell Do?

  • The metadata prepares the page for responsive browser layouts.
  • The stylesheet link tells the browser to load style.css from the same folder.
  • The status-shell class gives the dashboard a styling hook without declaring a machine-readable service state.
  • Save docs/index.html.
  • Use the Explorer context menu to reveal docs/index.html in Windows File Explorer.
  • Open index.html with Microsoft Edge.

You should see a blank page with Northstar Status in the browser tab. This confirms that Microsoft Edge loaded the correct local file.

Does the Local Page Fail to Open?

Confirm that the file is named index.html inside the docs folder. Check whether Windows added an extra text-file extension.

Help me open my local status page in Microsoft Edge.

The page header identifies the fictional service. The summary gives visitors an immediate answer about its current health.

  • Switch back to docs/index.html in Visual Studio Code.
  • Find the opening <main class="status-shell"> element.
  • Add the header plus operational summary directly below that element by pasting this code:
    <header class="page-header">
      <p class="eyebrow">LIVE SERVICE HEALTH</p>
      <h1>Northstar Status</h1>
      <p>Current availability for customer-facing services.</p>
    </header>

    <section class="summary operational" aria-label="Overall service status">
      <span class="status-dot" aria-hidden="true"></span>
      <div>
        <p class="summary-title">All systems operational</p>
        <p class="summary-copy">No active incidents are affecting customers.</p>
      </div>
    </section>

How Does the Summary Work?

  • The header names Northstar before presenting its current availability.
  • The summary pairs the visible operational state with supporting copy.
  • The accessibility label gives the summary a meaningful name for assistive technology.
  • Save docs/index.html.
  • Switch back to the local page in Microsoft Edge.
  • Refresh the page.

You should see LIVE SERVICE HEALTH above the Northstar title. You should also see All systems operational beneath the header.

Is the Summary Missing?

Confirm that the header plus summary sit between the opening and closing main elements. Save the file before refreshing Microsoft Edge.

Help me debug the missing Northstar summary.

Individual service rows make the headline status specific. Visitors can check Website, API, or Dashboard health from one screen.

  • Find the closing </section> element for the operational summary.
  • Add the service list plus footer directly below that element by pasting this code:
    <section class="services" aria-labelledby="services-title">
      <h2 id="services-title">Services</h2>
      <div class="service-row">
        <span>Website</span>
        <span class="badge">Operational</span>
      </div>
      <div class="service-row">
        <span>API</span>
        <span class="badge">Operational</span>
      </div>
      <div class="service-row">
        <span>Dashboard</span>
        <span class="badge">Operational</span>
      </div>
    </section>

    <footer>Last checked: Demo data for CI/CD practice</footer>

What Do the Service Rows Show?

  • Each service row pairs one service name with its current state.
  • The repeated badge class gives each state a consistent styling hook.
  • The footer identifies the content as demonstration data for CI/CD practice.
  • Save docs/index.html.
  • Switch back to Microsoft Edge.
  • Refresh the local page.

You should see Website, API, and Dashboard beneath the summary. Each row should show Operational on the right.

Are the Service Rows Incomplete?

Compare the three service-row elements. Each row needs one service name plus one operational badge.

Help me repair the service rows in my status page.

✔️ Awesome, I've got everything!

Your page structure is complete. Make sure docs/index.html is saved before adding the stylesheet.

ⓧ I'd like to double check the full code

Compare your complete docs/index.html file with this reference:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Northstar service status dashboard">
  <title>Northstar Status</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="status-shell">
    <header class="page-header">
      <p class="eyebrow">LIVE SERVICE HEALTH</p>
      <h1>Northstar Status</h1>
      <p>Current availability for customer-facing services.</p>
    </header>

    <section class="summary operational" aria-label="Overall service status">
      <span class="status-dot" aria-hidden="true"></span>
      <div>
        <p class="summary-title">All systems operational</p>
        <p class="summary-copy">No active incidents are affecting customers.</p>
      </div>
    </section>

    <section class="services" aria-labelledby="services-title">
      <h2 id="services-title">Services</h2>
      <div class="service-row">
        <span>Website</span>
        <span class="badge">Operational</span>
      </div>
      <div class="service-row">
        <span>API</span>
        <span class="badge">Operational</span>
      </div>
      <div class="service-row">
        <span>Dashboard</span>
        <span class="badge">Operational</span>
      </div>
    </section>

    <footer>Last checked: Demo data for CI/CD practice</footer>
  </main>
</body>
</html>

The browser now understands the dashboard content. Styling gives that content a centred surface with a clear visual hierarchy.

  • Create style.css inside the docs folder.
  • Add the page foundation to docs/style.css by pasting this code:
:root {
  color-scheme: dark;
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background: #07111f;
  color: #e5eefb;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 2rem 1rem;
  background:
    radial-gradient(circle at top left, rgba(56, 189, 248, 0.18), transparent 35%),
    #07111f;
}

What Does the Page Foundation Do?

  • The root rule establishes the dark colour palette plus the interface font stack.
  • The sizing rule keeps element dimensions predictable.
  • The body grid centres the dashboard inside the browser window.
  • Save docs/style.css.
  • Switch back to Microsoft Edge.
  • Refresh the local page.

You should see a dark page with a blue glow in the upper-left background. The dashboard content should sit near the centre of the window.

Does the Page Still Look Unstyled?

Confirm that style.css sits beside index.html inside the docs folder. Check that the HTML link uses href="style.css".

Help me find why my stylesheet is not loading.

The dashboard shell needs a clear boundary from the page background. Header styles then make the page title easy to scan.

  • Add the dashboard shell plus header styles below the body rule by pasting this code:
.status-shell {
  width: min(720px, 100%);
  padding: 2rem;
  border: 1px solid #20324a;
  border-radius: 1.25rem;
  background: rgba(10, 24, 43, 0.94);
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.35);
}

.page-header h1 {
  margin: 0.25rem 0 0.5rem;
  font-size: clamp(2rem, 6vw, 3.25rem);
}

.page-header p {
  color: #9fb2cb;
}

.eyebrow {
  margin: 0;
  color: #7dd3fc;
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.16em;
}

How Does the Dashboard Gain Hierarchy?

  • The status shell creates a rounded card that can shrink on narrow screens.
  • The title uses responsive sizing to remain prominent across window widths.
  • The eyebrow uses compact blue lettering to label the dashboard.
  • Save docs/style.css.
  • Switch back to Microsoft Edge.
  • Refresh the local page.

You should see the content inside a rounded dark card. The Northstar title should appear beneath a compact blue label.

Is the Dashboard Card Missing?

Confirm that the CSS selector is .status-shell. Check that it matches class="status-shell" in the HTML.

Help me debug the dashboard shell styles.

The summary needs visual spacing before its health colour can stand out. The operational rules add the green state panel plus its glowing dot.

  • Add the summary layout plus operational state styles below the header rules by pasting this code:
.summary {
  display: flex;
  gap: 1rem;
  align-items: center;
  margin: 2rem 0;
  padding: 1.25rem;
  border-radius: 1rem;
}

.summary.operational {
  border: 1px solid #166534;
  background: rgba(22, 101, 52, 0.18);
}

.status-dot {
  width: 0.9rem;
  height: 0.9rem;
  flex: 0 0 auto;
  border-radius: 999px;
  background: #4ade80;
  box-shadow: 0 0 0 0.35rem rgba(74, 222, 128, 0.14);
}

How Is the Operational State Communicated?

  • The summary uses a horizontal layout to place the status dot beside the copy.
  • The operational modifier adds a green border plus a tinted background.
  • The status dot becomes a compact green signal with a soft outer ring.
  • Save docs/style.css.
  • Switch back to Microsoft Edge.
  • Refresh the local page.

You should see the operational summary inside a green-tinted panel. A glowing green dot should appear beside the message.

Is the Operational Panel Still Plain?

Confirm that the summary section contains both summary plus operational in its class value. Check that the dot uses class="status-dot".

Help me debug the operational state styles.

Typography keeps the primary health state prominent. Muted supporting text leaves the main status easy to scan.

  • Add the summary text plus service heading styles below the status-dot rule by pasting this code:
.summary-title {
  margin: 0;
  color: #86efac;
  font-size: 1.1rem;
  font-weight: 800;
}

.summary-copy {
  margin: 0.3rem 0 0;
  color: #c8d5e6;
}

.services h2 {
  font-size: 1rem;
  color: #9fb2cb;
}

What Does the Typography Emphasise?

  • The summary title receives stronger weight plus a brighter operational colour.
  • The supporting copy stays muted so the state remains dominant.
  • The services heading uses a compact size to introduce the detailed rows.
  • Save docs/style.css.
  • Switch back to Microsoft Edge.
  • Refresh the local page.

You should see a brighter green operational title. The supporting message plus Services heading should appear softer.

Is the Summary Text Unchanged?

Compare .summary-title plus .summary-copy with the matching HTML classes. Check each selector's leading full stop.

Help me fix the summary typography.

The final rules align each service with its badge. They also keep the card readable when the browser becomes narrow.

  • Finish docs/style.css by adding the row plus responsive styles below the services heading rule:
.service-row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 0;
  border-top: 1px solid #20324a;
}

.badge {
  color: #86efac;
  font-weight: 700;
}

footer {
  margin-top: 1.5rem;
  color: #7186a0;
  font-size: 0.85rem;
}

@media (max-width: 520px) {
  .status-shell {
    padding: 1.25rem;
  }
}

How Does the Page Finish?

  • The row layout places each service name opposite its badge.
  • The footer uses smaller muted text to keep attention on service health.
  • The media query reduces card padding when the viewport is 520 pixels wide or narrower.
  • Save docs/style.css.
  • Switch back to Microsoft Edge.
  • Refresh the local page.
  • Narrow the Microsoft Edge window below 520 pixels.

You should see three separated service rows with aligned green badges. The card should remain readable inside the narrow window.

Does the Card Overflow?

Confirm that the media query closes after the .status-shell rule. Check that the main shell still uses width: min(720px, 100%).

Help me fix the responsive dashboard layout.

✔️ Awesome, I've got everything!

Your dashboard styling is complete. Make sure docs/style.css is saved before the final local check.

ⓧ I'd like to double check the full code

Compare your complete docs/style.css file with this reference:

:root {
  color-scheme: dark;
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background: #07111f;
  color: #e5eefb;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 2rem 1rem;
  background:
    radial-gradient(circle at top left, rgba(56, 189, 248, 0.18), transparent 35%),
    #07111f;
}

.status-shell {
  width: min(720px, 100%);
  padding: 2rem;
  border: 1px solid #20324a;
  border-radius: 1.25rem;
  background: rgba(10, 24, 43, 0.94);
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.35);
}

.page-header h1 {
  margin: 0.25rem 0 0.5rem;
  font-size: clamp(2rem, 6vw, 3.25rem);
}

.page-header p {
  color: #9fb2cb;
}

.eyebrow {
  margin: 0;
  color: #7dd3fc;
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.16em;
}

.summary {
  display: flex;
  gap: 1rem;
  align-items: center;
  margin: 2rem 0;
  padding: 1.25rem;
  border-radius: 1rem;
}

.summary.operational {
  border: 1px solid #166534;
  background: rgba(22, 101, 52, 0.18);
}

.status-dot {
  width: 0.9rem;
  height: 0.9rem;
  flex: 0 0 auto;
  border-radius: 999px;
  background: #4ade80;
  box-shadow: 0 0 0 0.35rem rgba(74, 222, 128, 0.14);
}

.summary-title {
  margin: 0;
  color: #86efac;
  font-size: 1.1rem;
  font-weight: 800;
}

.summary-copy {
  margin: 0.3rem 0 0;
  color: #c8d5e6;
}

.services h2 {
  font-size: 1rem;
  color: #9fb2cb;
}

.service-row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 0;
  border-top: 1px solid #20324a;
}

.badge {
  color: #86efac;
  font-weight: 700;
}

footer {
  margin-top: 1.5rem;
  color: #7186a0;
  font-size: 0.85rem;
}

@media (max-width: 520px) {
  .status-shell {
    padding: 1.25rem;
  }
}
Inspect the local dashboard

A visual check confirms that people can understand the page. A source check confirms that the deliberate machine-readable gap remains in place.

Before you refresh, which visible details do you expect to confirm on the finished dashboard?

  • Return to the local page in Microsoft Edge.
  • Refresh the page.
  • Confirm that the summary says All systems operational.
  • Confirm that the Website row says Operational.
  • Confirm that the API row says Operational.
  • Confirm that the Dashboard row says Operational.
  • Narrow the browser window below 520 pixels.
  • Confirm that the status card remains readable inside the window.

That is your first visible win. The Northstar dashboard now communicates service health across wide or narrow screens.

  • Switch back to docs/index.html in Visual Studio Code.
  • Locate the opening <main class="status-shell"> element.
  • Confirm that the element has no data-status attribute.

The page reports healthy services to a person while leaving automation without a matching state attribute. That intentional mismatch gives the upcoming quality gate a real defect to expose.

Publish the repository

A Git commit records the dashboard state you tested. Publishing that commit gives the next workflow a public repository to validate.

  • Select Source Control in the Visual Studio Code sidebar.
  • Initialize a repository from the Source Control view.
  • Stage both files from the Changes area.
  • Enter Build status page in the commit message field.
  • Select the commit control.

You should see an empty Changes area after the commit succeeds. Your local repository now has a snapshot containing both status page files.

Does the Commit Fail?

Confirm that both files are staged before committing. Check that the configured Git identity from the previous step is still available.

Help me troubleshoot my first status page commit.

The upcoming workflow listens to the main branch. Rename the current branch before publishing so the local and remote branches share that name.

  • Switch back to the Visual Studio Code terminal from earlier.
  • Rename the current branch to main by running this command:
git branch -m main

What Does This Command Do?

The command renames the current local branch to main. The commit history stays attached to the renamed branch.

  • Check the branch indicator in the Visual Studio Code Status Bar.

You should see main as the active branch. This confirms that the local branch is ready for the later workflow trigger.

Does the Branch Name Stay Unchanged?

Confirm that the terminal is inside the ai-cicd-status-page folder. The command only works inside a Git repository.

Help me rename my local branch to main.

Publishing creates the remote repository before uploading your local commit. Visual Studio Code may ask you to authorise GitHub even though Copilot is already signed in.

  • Open the Command Palette from the Visual Studio Code menu.
  • Enter Publish to GitHub in the Command Palette.
  • Select Publish to GitHub from the results.
  • Approve the GitHub authorisation request if it appears.
  • Enter ai-cicd-status-page as the repository name.
  • Choose the public repository option.

Publishing can take a short moment while Visual Studio Code creates the repository and uploads the commit. You should see a confirmation when the local main branch is connected to GitHub.

Did Publishing Fail?

Confirm that Visual Studio Code uses the same GitHub account as Copilot. Check that the repository name is exactly ai-cicd-status-page.

Help me troubleshoot publishing this repository.

Before you check GitHub, which folder do you expect the published repository to contain?

  • Return to GitHub in Microsoft Edge from earlier.
  • Open your account's repository list.
  • Select ai-cicd-status-page.
  • Confirm that the repository is public.
  • Confirm that main is the selected branch.
  • Open the docs folder.
  • Confirm that index.html is listed.
  • Confirm that style.css is listed.

Strong work. Your public repository now contains the same Northstar dashboard that you tested locally.

Your status page is visible locally plus committed on GitHub. Next, you will add a quality gate that catches the missing machine-readable state before an artifact is created.

Let CI Catch a Real Defect

Your Northstar dashboard now gives the pipeline a real page to protect. Its visible operational message currently speaks only to people.

Automation needs an exact machine-readable contract. A GitHub Actions workflow uses a PowerShell check to enforce that contract before it packages a build artifact.

In this step, get ready to:
  • Create a PowerShell script that defines the page contract.
  • Create a test-only GitHub Actions workflow that runs the quality gate.
  • Push the CI commit to trace the workflow result.
Create the PowerShell quality gate

An automated quality gate checks the page against a fixed contract. This script requires the files, visible content, service rows, stylesheet link, plus an exact machine-readable status.

  • In the Visual Studio Code Explorer sidebar, select the ai-cicd-status-page folder.
  • Click the New Folder icon.
  • Name the new folder scripts.
  • Select the scripts folder.
  • Click the New File icon.
  • Name the file test-status-page.ps1.
  • Build the quality gate in scripts/test-status-page.ps1 by pasting this code:
$ErrorActionPreference = "Stop"

$repoRoot = Split-Path -Parent $PSScriptRoot
$indexPath = Join-Path $repoRoot "docs\index.html"
$stylePath = Join-Path $repoRoot "docs\style.css"

if (-not (Test-Path $indexPath)) {
    throw "Missing docs/index.html"
}

if (-not (Test-Path $stylePath)) {
    throw "Missing docs/style.css"
}

$html = Get-Content -Path $indexPath -Raw

$requiredFragments = @(
    '<main class="status-shell" data-status="operational">',
    'All systems operational',
    'class="service-row"',
    'href="style.css"'
)

foreach ($fragment in $requiredFragments) {
    if (-not $html.Contains($fragment)) {
        throw "Required HTML fragment not found: $fragment"
    }
}

Write-Host "All status page checks passed."

What does this quality gate check?

  • The $ErrorActionPreference setting stops the script when a check throws an error.
  • The path variables locate the repository plus its two required page files.
  • The two Test-Path checks reject a missing HTML file or stylesheet.
  • The $requiredFragments array defines the exact HTML contract.
  • The foreach loop throws a focused message when any required fragment is absent.
  • Save scripts/test-status-page.ps1.
  • Confirm that test-status-page.ps1 appears inside the scripts folder in the Explorer sidebar.

Is the script in the wrong folder?

Check that scripts sits directly inside ai-cicd-status-page. Move the file into that folder if it appears beside ai-cicd-status-page.

Help me check my quality gate file location.

✔️ Awesome, I've got everything!

Great. Your repository now contains the PowerShell quality gate that defines the page contract.

ⓧ I'd like to double check the full code

$ErrorActionPreference = "Stop"

$repoRoot = Split-Path -Parent $PSScriptRoot
$indexPath = Join-Path $repoRoot "docs\index.html"
$stylePath = Join-Path $repoRoot "docs\style.css"

if (-not (Test-Path $indexPath)) {
    throw "Missing docs/index.html"
}

if (-not (Test-Path $stylePath)) {
    throw "Missing docs/style.css"
}

$html = Get-Content -Path $indexPath -Raw

$requiredFragments = @(
    '<main class="status-shell" data-status="operational">',
    'All systems operational',
    'class="service-row"',
    'href="style.css"'
)

foreach ($fragment in $requiredFragments) {
    if (-not $html.Contains($fragment)) {
        throw "Required HTML fragment not found: $fragment"
    }
}

Write-Host "All status page checks passed."

How to use this reference

Compare this reference with your saved file from top to bottom. Every path, required fragment, plus error message must match.

Add the test-only CI workflow

A workflow connects the quality gate to each push on main. This first version contains only the test job, which keeps deployment behind the validation result.

  • In the Explorer sidebar, select the ai-cicd-status-page folder.
  • Click the New Folder icon.
  • Name the new folder .github.
  • Inside .github, create a folder named workflows.
  • Select the workflows folder.
  • Click the New File icon.
  • Name the file pages.yml.
  • Define the test-only workflow in .github/workflows/pages.yml by pasting this code:
name: Status Page CI/CD

on:
  push:
    branches:
      - main
  workflow_dispatch:

permissions:
  contents: read

jobs:
  test:
    name: Test and package
    runs-on: windows-latest
    steps:
      - name: Check out repository
        uses: actions/checkout@v7.0.1

      - name: Validate status page
        shell: pwsh
        run: ./scripts/test-status-page.ps1

      - name: Upload Pages artifact
        uses: actions/upload-pages-artifact@v5.0.0
        with:
          path: docs

How does this workflow protect the page?

  • The push trigger runs the workflow when a commit reaches main.
  • The workflow_dispatch trigger supports a manual run from GitHub Actions.
  • The repository-level contents: read permission gives the workflow read-only access to the source.
  • The test job uses a Windows runner so it can execute the PowerShell script.
  • The validation step runs the contract before artifact packaging.
  • The upload step packages the docs directory only when every earlier step succeeds.
  • Save .github/workflows/pages.yml.
  • Confirm that pages.yml appears inside .github/workflows in the Explorer sidebar.

Does the workflow look misaligned?

YAML uses indentation to group settings. Compare the spacing beneath jobs, test, steps, plus with.

Help me check my workflow indentation.

✔️ Awesome, I've got everything!

Your workflow now checks each push to main with a Windows test job before it attempts artifact upload.

ⓧ I'd like to double check the full code

name: Status Page CI/CD

on:
  push:
    branches:
      - main
  workflow_dispatch:

permissions:
  contents: read

jobs:
  test:
    name: Test and package
    runs-on: windows-latest
    steps:
      - name: Check out repository
        uses: actions/checkout@v7.0.1

      - name: Validate status page
        shell: pwsh
        run: ./scripts/test-status-page.ps1

      - name: Upload Pages artifact
        uses: actions/upload-pages-artifact@v5.0.0
        with:
          path: docs

How to use this reference

Compare this reference with your saved workflow. The file should end after the path: docs setting because deployment comes later.

Push the workflow and inspect the failure

A workflow run turns the contract into visible evidence. GitHub places the exact log inside the run's job, so finding the relevant line can feel fiddly.

  • Select the Source Control icon in the Activity Bar.
  • Stage scripts/test-status-page.ps1 using the plus icon beside the file.
  • Stage .github/workflows/pages.yml using the plus icon beside the file.
  • Enter Add status page CI in the commit message field.
  • Select Commit.
  • Confirm that the Source Control sidebar no longer lists the two files as pending changes.

Before you push, do you think the visible status message gives this quality gate enough information to pass?

  • Push the commit using the Source Control sync control.
  • Switch back to Microsoft Edge.
  • Return to the public ai-cicd-status-page repository.
  • Select the Actions tab.
  • Select Status Page CI/CD.
  • Open the newest workflow run.
  • Open the Test and package job after the run finishes.
  • Expand the Validate status page step.

You'll see the validation fail with Required HTML fragment not found: <main class="status-shell" data-status="operational">.

Why did the quality gate stop?

The page currently opens with <main class="status-shell">. The quality gate requires the exact machine-readable status fragment shown in the log.

The failed validation stops the job before artifact packaging. This is the intended defect detection.

  • Inspect the Upload Pages artifact step in the same job.

You'll see that Upload Pages artifact did not run. No Pages artifact was created from the page that failed its contract.

That red run proves your quality gate works: the missing machine-readable state cannot become a deployable artifact.

Can't find the failed validation log?

Make sure you opened the newest run under Status Page CI/CD. Expand Test and package, then select Validate status page.

Help me locate the failed quality gate log.

Your pipeline has caught a real contract defect before packaging the page. Next, you'll use Copilot Chat to explain the log while keeping the quality gate intact.

Diagnose the Failure with Copilot

Your status page now has a quality gate. The failed GitHub Actions run proves that gate can stop an invalid artifact.

A red workflow identifies the symptom. In this step, Copilot Chat will turn the failing log into the smallest HTML repair while keeping the test intact.

In this step, get ready to:
  • Ask Copilot Chat to explain the failure without weakening the quality gate.
  • Compare the diagnosis with the PowerShell check before applying the HTML repair.
  • Push the repaired commit through the workflow.
Ask Copilot to diagnose the log

Ask mode explains code without editing your files automatically. The prompt includes the real workflow message so Copilot can reason from evidence.

  • Switch back to Visual Studio Code.
  • Select the chat icon in the Visual Studio Code title bar.
  • Select Ask from the agents dropdown.
  • Paste the exact diagnosis request below into Copilot Chat:
This GitHub Actions PowerShell check failed with: Required HTML fragment not found: <main class="status-shell" data-status="operational">. Explain the failure and propose the smallest HTML-only fix. Do not weaken the test.

Why does this prompt work?

  • The failure text gives Copilot the exact contract that the page violated.
  • The phrase smallest HTML-only fix keeps the repair focused on the page markup.
  • The instruction Do not weaken the test preserves the quality gate.
  • Press Enter to submit the request.

Copilot should explain that docs/index.html lacks the exact data-status="operational" attribute. Its proposed repair should add that attribute to the opening main element without changing the test script.

Did Copilot suggest changing the test?

  • Return to the original request if the response removes the required fragment or changes scripts/test-status-page.ps1.

Ask for help reviewing the response: Check whether my Copilot diagnosis preserves the quality gate.

Compare the diagnosis and repair the page

The PowerShell script defines the machine-readable contract for the page. Your visible status message already passes its human-facing check.

The opening main element is the remaining mismatch. Comparing the test with the page confirms that Copilot found the correct repair.

  • Select scripts/test-status-page.ps1 in the Visual Studio Code Explorer sidebar.
  • Find the required fragment <main class="status-shell" data-status="operational">.
  • Confirm that Copilot's recommendation preserves this required fragment.
  • Select docs/index.html in the Explorer sidebar.
  • Locate the current opening element:
  <main class="status-shell">

Why does this line fail?

The visible summary appears later in the page. The quality gate checks the opening element for a machine-readable operational state.

This line has the correct styling class. It is missing the state that automation requires.

  • Replace the current opening element with this corrected line:
  <main class="status-shell" data-status="operational">

What changes here?

  • The data-status="operational" attribute exposes the service state to the quality gate.
  • The existing status-shell class keeps the page styling unchanged.
  • Save docs/index.html.

✔️ Awesome, I've got everything!

Your page now carries the visible design plus its machine-readable operational state.

ⓧ I'd like to double check the full code

  • Compare your complete docs/index.html file with this reference:
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Northstar service status dashboard">
  <title>Northstar Status</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="status-shell" data-status="operational">
    <header class="page-header">
      <p class="eyebrow">LIVE SERVICE HEALTH</p>
      <h1>Northstar Status</h1>
      <p>Current availability for customer-facing services.</p>
    </header>

    <section class="summary operational" aria-label="Overall service status">
      <span class="status-dot" aria-hidden="true"></span>
      <div>
        <p class="summary-title">All systems operational</p>
        <p class="summary-copy">No active incidents are affecting customers.</p>
      </div>
    </section>

    <section class="services" aria-labelledby="services-title">
      <h2 id="services-title">Services</h2>
      <div class="service-row">
        <span>Website</span>
        <span class="badge">Operational</span>
      </div>
      <div class="service-row">
        <span>API</span>
        <span class="badge">Operational</span>
      </div>
      <div class="service-row">
        <span>Dashboard</span>
        <span class="badge">Operational</span>
      </div>
    </section>

    <footer>Last checked: Demo data for CI/CD practice</footer>
  </main>
</body>
</html>
Push the repair and verify the workflow

The workflow evaluates the commit stored on GitHub. Sending this one-line repair through the same unchanged gate proves the diagnosis was correct.

  • Select the Source Control icon in the Visual Studio Code Activity Bar.
  • Select the plus icon beside docs/index.html to stage the repaired file.

You should see docs/index.html move into the staged section.

  • Enter Fix machine-readable service status in the commit message field.
  • Create the commit with the Source Control commit control.

The repaired file should leave the pending changes list once the commit succeeds.

  • Push the commit with the Source Control push control you used earlier.

GitHub Actions starts a new Status Page CI/CD run for the pushed commit.

Before you inspect the new run, do you expect the unchanged quality gate to accept the repaired page?

  • Switch back to the public repository in Microsoft Edge.
  • Select Actions in the repository navigation.
  • Select Status Page CI/CD from the workflow list.
  • Open the newest run created by Fix machine-readable service status.
  • Inspect the artifact listed on the run summary.
  • Select the Test and package job.
  • Expand the Validate status page step.
  • Expand the Upload Pages artifact step.

You should see successful results for both workflow steps. The run summary should list a github-pages artifact.

That one-line repair now passes the same quality gate that caught the defect.

Is the newest workflow still failing?

  • Compare the opening element in docs/index.html with the exact required fragment in scripts/test-status-page.ps1.
  • Confirm that the newest run belongs to the Fix machine-readable service status commit.
  • Check that Validate status page succeeds before expecting Upload Pages artifact to run.

Get help with the failed run: Help me diagnose why my repaired status page workflow still fails.

Your validated page now produces a Pages artifact. Next, you will connect that artifact to a dependent deployment job and publish Northstar with GitHub Pages.

Turn Passing CI into Continuous Deployment

Your repaired status page now passes its GitHub Actions quality gate. The successful run also packages the validated docs folder as a build artifact.

A green check proves the page is ready. Continuous deployment needs a dependent job with permission to release that artifact through GitHub Pages.

In this step, get ready to:
  • Set GitHub Actions as the repository's Pages publishing source.
  • Connect the passing test job to a least-privilege deployment job.
  • Push the completed workflow and visit the public Northstar dashboard.
Choose GitHub Actions as the publishing source

The repository must accept deployments from your custom workflow. This setting gives the deployment job a publishing destination.

  • Return to the public ai-cicd-status-page repository in Microsoft Edge.
  • Select Settings in the repository navigation.
  • Select Pages in the settings sidebar.
  • Select GitHub Actions from the Source options under Build and deployment.

You'll see GitHub Actions selected as the publishing source. The repository can now accept deployments from the workflow you control.

Connect validation to deployment

A separate deploy job keeps release access away from the validation steps. Its needs: test dependency makes deployment wait for a successful quality gate.

  • Switch back to Visual Studio Code.
  • In .github/workflows/pages.yml, place your cursor on a new line below path: docs.
  • Complete the workflow by pasting this job definition:
  deploy:
    name: Deploy
    needs: test
    permissions:
      pages: write
      id-token: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v5.0.1

What does this job do?

  • The needs: test dependency allows deployment only after the test job succeeds.
  • The job-level least-privilege permissions grant only pages: write plus id-token: write.
  • The github-pages environment exposes the published address through ${{ steps.deployment.outputs.page_url }}.
  • The actions/deploy-pages@v5.0.1 action publishes the Pages artifact created by the test job.
  • Save .github/workflows/pages.yml.
  • Select Source Control in Visual Studio Code.

You'll see .github/workflows/pages.yml as the only modified file. That single change turns the existing quality gate into a release pipeline.

Workflow indentation look wrong?

  • Check that deploy: aligns with test: under jobs:.
  • Check that every line inside deploy: uses consistent spaces.
  • Confirm that the deployment job sits below the test job.

Help me check the YAML structure in my Pages workflow.

✔️ Awesome, I've got everything!

Your saved workflow now has a test job followed by a dependent deploy job.

ⓧ I'd like to double check the full code

name: Status Page CI/CD

on:
  push:
    branches:
      - main
  workflow_dispatch:

permissions:
  contents: read

jobs:
  test:
    name: Test and package
    runs-on: windows-latest
    steps:
      - name: Check out repository
        uses: actions/checkout@v7.0.1

      - name: Validate status page
        shell: pwsh
        run: ./scripts/test-status-page.ps1

      - name: Upload Pages artifact
        uses: actions/upload-pages-artifact@v5.0.0
        with:
          path: docs

  deploy:
    name: Deploy
    needs: test
    permissions:
      pages: write
      id-token: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v5.0.1
Push the workflow and visit the public site

A push to main now triggers the complete workflow. The test job validates and packages the page before deployment receives the artifact.

  • Stage .github/workflows/pages.yml in Visual Studio Code Source Control.

You'll see .github/workflows/pages.yml listed as staged for the next commit.

  • Enter Deploy validated page in the commit message box.
  • Select Commit.

Visual Studio Code records the workflow change in your local repository. The workflow file leaves the pending change list.

Before you push, which job do you expect to start first? The next run reveals the answer.

  • Push the commit to GitHub from Source Control.
  • Return to the repository in Microsoft Edge.
  • Select Actions.
  • Select Status Page CI/CD from the workflow list.
  • Open the newest run for Deploy validated page.

You'll see Test and package run first. After it succeeds, you'll see Deploy start.

  • Confirm Validate status page shows a successful result.
  • Confirm Upload Pages artifact shows a successful result.
  • Confirm Deploy to GitHub Pages shows a successful result.

That job order proves the public release cannot begin until the same page has passed validation.

GitHub Pages can take up to 10 minutes to publish after a push. A short wait here is normal while the public address becomes available.

Before you open the site, do you expect its visible status to match the validated HTML? The public page provides the final check.

  • Return to the repository.
  • Select Settings.
  • Select Pages.
  • Select Visit site.

You'll see the Northstar Status heading above All systems operational. Each of the three service rows shows Operational.

Site not ready?

  • Wait up to 10 minutes after the push.
  • Refresh the Pages settings page.
  • Return to Actions if publication is still unavailable.
  • Confirm the Deploy to GitHub Pages step succeeded.

Help me diagnose why my GitHub Pages site is unavailable after a successful deployment.

You completed the full DevOps loop. Every future push to main now has to pass validation before it can update the public Northstar dashboard.

Secret mission

Support a Degraded Service State

Your pipeline can release an operational dashboard. Now extend its contract so a degraded API incident reaches customers only after the page state and summary copy pass validation.

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

The public repository uses free standard GitHub Actions runners. GitHub Pages adds no ongoing charge for this project.

Resources you used:

  • Public GitHub repository named ai-cicd-status-page.
  • Local Git working folder named ai-cicd-status-page.
  • Status Page CI/CD workflow stored in the public repository.
  • Public GitHub Pages deployment for the Northstar status page.

Keep everything running

No action needed. Choose this if you want to keep the Northstar status page online or continue improving its pipeline.

  • Leave the public ai-cicd-status-page repository in place.
  • Keep the GitHub Pages deployment published.
  • Push future updates to main when you want the workflow to validate and deploy them.

Pause - I'll come back to this later

Unpublishing the site pauses public access while preserving your repository. A future successful deployment can publish the site again.

  • Return to the public ai-cicd-status-page repository in Microsoft Edge.
  • Select Settings in the repository navigation.
  • Select Pages in the settings sidebar.
  • Open the live deployment menu.
  • Choose Unpublish site.
  • Refresh the former public site URL.

You should no longer see the Northstar dashboard at the public URL. Your commits and workflow remain available in the repository.

Delete - I don't want to use this again

Deleting the repository permanently removes the public project. Your local working folder stays on your computer until you remove it separately.

  • Return to the public ai-cicd-status-page repository in Microsoft Edge.
  • Select Settings in the repository navigation.
  • Select General in the settings sidebar.
  • Scroll to Danger Zone.
  • Select Delete this repository.
  • Complete GitHub's confirmation process.
  • Return to the former repository URL to confirm that it no longer loads.

That is the irreversible part complete. The repository deletion also removes the workflow and its public Pages deployment.

  • Use Windows search to find the local ai-cicd-status-page folder.
  • Open the folder's saved location.
  • Delete the ai-cicd-status-page folder.
  • Remove the folder from the Windows deleted-files area to make the deletion permanent.
  • Search for ai-cicd-status-page again to verify that no local working folder remains.

Your public repository and local working folder are now gone. No project resource remains active.

Nice Work!

Nice Work!

You did it! Your Northstar status page now passes a quality gate before every public deployment.

You've learned how to:

  • Publish a responsive Northstar status dashboard from a public GitHub repository. Track each release as a Git commit.
  • Build an automated quality gate in GitHub Actions with a PowerShell script. See the gate reject a page whose machine-readable state is missing before any deployment artifact is created.
  • Use Copilot Chat to explain a real CI/CD failure. Apply the smallest HTML repair. Release the validated artifact through GitHub Pages after the test job passes.
  • Secret Mission: Extend the dashboard to show a degraded service state with an API latency incident notice. Update the validation contract so that state still passes before deployment.

Ready to quiz yourself?