Deploy a Status Page with GitHub Actions

Publish a live status page with GitHub Actions and GitHub Pages.

Introduction

30 Second Summary

A public status page loses trust when its information falls behind. Manual publishing turns a small update into another task someone has to remember.

In this project, you will build a live status page for a fictional API. GitHub Actions will publish each push to main as the latest site on GitHub Pages.

What You'll Build

You will refresh a public Northstar API page after a push to see your latest status update live.

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

  • A styled service-status page that shows an Operational badge above three service health cards.
  • A public repository where every site update is preserved as a commit you can inspect.
  • A push-to-deploy workflow that updates your live URL after each site change reaches main.
  • Secret Mission: Add path filters so README.md-only commits skip deployment while site changes still publish.

Are there any prerequisites?

You need a GitHub account plus internet access. This guide prepares Git, GNU nano, SSH authentication, and the Linux Mint XFCE terminal workflow from scratch.

Before We Start

Before any hands-on work begins, this step locks in what you are building and why automatic deployment matters. Your goal is a public Northstar API status page whose pushes to the main branch deploy automatically.

Install and Configure Terminal Tools

Every future deployment begins with a change saved on your Linux Mint machine. Git records that change for the workflow ahead.

GNU nano gives you a predictable terminal editor for the status page files. This step confirms both tools before you create anything.

In this step, get ready to:
  • Confirm the terminal toolchain is available.
  • Install any missing terminal package.
  • Configure your global Git author identity.
Check your terminal tools

Version checks reveal whether the commands are ready before you depend on them. They also give you a clear starting point if either tool is missing.

  • Open Linux Mint XFCE Terminal from the application menu.
  • Check the installed tool versions by running these commands:
git --version
nano --version

What do these commands check?

  • The git --version command prints the installed Git version.
  • The nano --version command prints the installed GNU nano version.

✔️ Both commands show versions

Good, both tools are ready for the work ahead.

ⓧ One or both commands are unavailable

A missing command means its package still needs to be installed. Linux Mint may request your administrator password before changing installed packages.

  • Refresh Linux Mint's package information if git --version was unavailable by running this command:
sudo apt-get update

What does this command do?

This command refreshes the package information Linux Mint uses to locate available software. Fresh package information helps the installation find the distribution-managed Git package.

  • Install Git by running this command:
sudo apt-get install git

What does this command do?

This command installs Git through Linux Mint's package system. Confirm the installation if the package manager asks for approval.

  • Open Linux Mint Software Manager from the application menu if nano --version was unavailable.
  • Search for the nano package.
  • Select the nano package.
  • Click Install.
  • Return to Linux Mint XFCE Terminal after the installation completes.
  • Check both tools again by running these commands:
git --version
nano --version

What should I see?

Each command should now print installed version information. This confirms Linux Mint can find both tools from the terminal.

Still missing a command?

  • Confirm the package installation completed before running the version check again.
  • Check that your internet connection is active if Linux Mint cannot refresh its package information.

Help me troubleshoot a missing terminal tool.

Configure your Git author identity

Git adds an author identity to each commit. Your global settings become the default for future repositories.

  • Replace YOUR_NAME with the author name you want attached to future commits.
  • Replace YOUR_EMAIL with an email connected to your GitHub account.
  • Configure both global values by running the edited commands below:
git config --global user.name "YOUR_NAME"
git config --global user.email "YOUR_EMAIL"

What do these settings control?

  • The --global option makes this identity the default for future repositories on your machine.
  • The user.name setting records the author name attached to your commits.
  • The user.email setting records the email attached to your commits.

Identity command rejected?

  • Keep each name or email value inside straight double quotes.
  • Confirm each command begins with git config --global.

Help me fix my Git identity commands.

Verify your setup

Reading the stored configuration proves that Git saved the values you entered. The output should match your chosen identity exactly.

  • Display your saved author identity by running these commands:
git config --global user.name
git config --global user.email

What should I see?

The first command should print your configured author name. The second command should print your GitHub-connected email.

Before you run the final checks, what do you expect each command to confirm?

  • Verify both terminal tools by running these commands:
git --version
nano --version

What should I see?

Both commands should print installed version information. This proves the terminal can run Git and GNU nano.

Your terminal foundation is ready: both version checks succeed.

Seeing a missing version result?

  • Return to the matching installation tab above if either command remains unavailable.
  • Confirm you typed each command with two hyphens before version.

Help me understand why a version check is failing.

Git can now identify your work, while GNU nano is ready for the files ahead. Next, you will connect this Linux Mint machine to GitHub with SSH authentication.

Authenticate with GitHub SSH

Your Git identity now labels every future commit with the right author. The next link must let this machine send those commits to GitHub.

SSH authentication uses a key pair to prove that this Linux Mint machine belongs to you. The private key stays on your machine.

GitHub stores the public key. Matching the two gives your terminal permission to push.

In this step, get ready to:
  • Create or reuse an Ed25519 SSH key pair.
  • Register the public key with GitHub for authentication.
  • Verify that the terminal can authenticate to GitHub.
Create or reuse an Ed25519 key

An Ed25519 key pair has a private file at ~/.ssh/id_ed25519. Its shareable public half lives at ~/.ssh/id_ed25519.pub.

  • Check the SSH directory for an existing key by running this command:
ls -al ~/.ssh

What does this command check?

The ls command lists the files inside ~/.ssh. The -al flags include hidden files plus details about each file.

The output shows whether an Ed25519 key pair already exists on this machine.

✔️ I see id_ed25519.pub

Good news. Your Ed25519 key pair is already available for the SSH agent.

ⓧ I do not see id_ed25519.pub

A new key gives this machine its own identity. The command asks for a save location plus a passphrase.

  • Replace YOUR_EMAIL in the command below with your GitHub-connected email.
  • Press Enter when the command asks where to save the key.
  • Enter a memorable passphrase when the command requests one.
  • Re-enter the same passphrase when the confirmation prompt appears.
  • Create the Ed25519 key pair by running this command:
ssh-keygen -t ed25519 -C "YOUR_EMAIL"

What does this command create?

The Ed25519 algorithm creates the private key plus its matching public key. The -C value labels the pair with your GitHub-connected email.

Keep id_ed25519 private. You will share only id_ed25519.pub with GitHub.

You should see confirmation that both key files were saved under ~/.ssh. The command also displays the key fingerprint plus its randomart.

Having trouble creating the key?

  • Return to the first tab if the terminal says that id_ed25519 already exists. This avoids replacing a key that another service may use.
  • Check that your email remains inside the quotation marks if the command reports an input problem.
  • Confirm that the key was saved to ~/.ssh/id_ed25519 if later commands cannot find it.

Help me fix my Ed25519 key setup on Linux Mint.

Load and register the public key

The SSH agent keeps your private key available during this terminal session. GitHub needs the matching public key before it can recognize the machine.

  • Prepare to enter your key passphrase if ssh-add requests it.
  • Start the SSH agent by running these commands:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
cat ~/.ssh/id_ed25519.pub

What do these commands do?

  • The first command starts the SSH agent for your current terminal session.
  • The second command loads your private key into the agent.
  • The third command prints the public key that GitHub can safely store.

You should see an agent process number followed by confirmation that the identity was added. The final output line is your public key.

  • Copy the entire final line from the terminal output.
  • In your browser, sign in to GitHub.
  • Click your profile picture in the upper-right corner.
  • Click Settings.

GitHub keeps authentication keys in the access settings for your account. The key type identifies this public key as permission for repository connections.

  • Click SSH and GPG keys in the Access section of the sidebar.
  • Click New SSH key or Add SSH key.
  • Enter Linux Mint XFCE in the Title field.
  • Select Authentication as the key type.
  • Paste the copied public key into the Key field.
  • Click Add SSH key.
  • Confirm access to your account if GitHub requests it.

Your public key is now registered. GitHub can use it to recognize authentication attempts from this Linux Mint machine.

Unable to add the public key?

  • Copy the complete final line from the terminal output without adding extra text.
  • Confirm that Authentication is selected as the key type.
  • Use a different title if another key in your account already uses Linux Mint XFCE.

Help me register my Linux Mint public SSH key with GitHub.

Test the GitHub connection

The final connection test asks GitHub to identify the account linked to your loaded key. On the first connection, SSH also asks you to verify GitHub's host fingerprint.

  • Open GitHub's published SSH key fingerprints in your browser.
  • Locate the Ed25519 fingerprint SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
  • Compare any fingerprint prompt in the terminal with that official value.
  • Enter yes only when the fingerprints match.

Before you test the connection, do you think GitHub can now connect this machine to your account?

  • Test SSH authentication with GitHub by running this command:
ssh -T git@github.com

What does this test prove?

The ssh -T git@github.com command attempts an authenticated connection without requesting a shell. GitHub checks whether the presented key matches one registered to your account.

A successful test still exits with code 1 because GitHub does not provide interactive shell access.

You should see Hi USERNAME! You've successfully authenticated, but GitHub does not provide shell access. The greeting contains your GitHub username.

That's the connection secured. Your terminal can now authenticate pushes to GitHub without sending your account password.

GitHub does not recognize the key?

  • Repeat the agent-loading commands above if you started a new terminal session.
  • Compare the public key saved in GitHub with the final output from the previous command block.
  • Confirm that the saved GitHub key uses the Authentication type.

Help me troubleshoot my GitHub SSH authentication test.

Your Linux Mint terminal now has an authenticated route to GitHub. Next, you will build the local status page that this connection eventually pushes online.

Build the Local Status Page

Your Linux Mint machine can now authenticate to GitHub over SSH. The deployment still needs a page worth publishing.

You will create a working baby version in a local Git repository. GNU nano will turn the HTML structure into a browser-ready status page with CSS styling.

In this step, get ready to:
  • Initialize the local status-page repository on the main branch.
  • Build the Northstar API page structure.
  • Style the page and verify it in your browser.
Initialize the local repository

A repository gives every future page change a history. Starting on main also prepares the project for the deployment trigger you will add later.

  • Initialize the repository inside your Home directory by running these commands:
cd ~/Desktop
git init -b main ~/linux-status-page
cd ~/linux-status-page

What do these commands do?

  • The first command gives you a predictable starting location before creating the project.
  • The second command creates ~/linux-status-page as a Git repository with main as its initial branch.
  • The final command moves your terminal into the new repository.

You should see confirmation that Git initialized an empty repository. Your terminal is now working inside ~/linux-status-page.

Repository not initializing?

  • Check that the command uses ~/linux-status-page as the destination.
  • Confirm that your terminal prompt shows linux-status-page after the final command.

Help me fix the local repository setup.

Build the page structure

The first version needs enough structure to work before styling is added. Its header gives the overall state while the footer records how the page is deployed.

  • Open index.html in GNU nano by running this command:
nano index.html

What does this command do?

GNU nano opens index.html inside ~/linux-status-page. It creates the file when it does not already exist.

  • Create the page shell by pasting this code into index.html:
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Northstar API Status</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="status-shell">
    <header class="hero">
      <p class="eyebrow">LIVE SERVICE STATUS</p>
      <h1>Northstar API</h1>
      <p class="summary">All systems operational.</p>
      <span class="overall-status">Operational</span>
    </header>

    <footer>
      <p>Deployment: <strong>Manual draft</strong></p>
      <p>Hosting: GitHub Pages</p>
    </footer>
  </main>
</body>
</html>

What does this structure do?

  • The stylesheet link tells the browser to load the visual rules from style.css.
  • The status-shell element contains the complete status-page interface.
  • The hero presents the service name with its overall health.
  • The footer identifies this version as a manual draft.
  • Save index.html by pressing Ctrl+O.
  • Confirm the filename by pressing Enter.
  • Open the linux-status-page folder from your Home directory in the Linux Mint file manager.
  • Double-click index.html to open it in your default browser.

You should see the Northstar API heading with an Operational label. The page still uses the browser's default appearance.

Page not opening?

  • Confirm that index.html is inside ~/linux-status-page.
  • Check nano's status bar to confirm that the file was written successfully.

Help me open my local status page.

The page now has an overall state. Each individual service also needs a card so visitors can scan its health.

  • Switch back to GNU nano.
  • Place your cursor on the blank line directly above <footer>.
  • Add the service grid by pasting this code:
    <section class="service-grid" aria-label="Current service health">
      <article class="status-card">
        <div>
          <h2>Public API</h2>
          <p>Requests and authentication</p>
        </div>
        <span class="status-pill">Operational</span>
      </article>

      <article class="status-card">
        <div>
          <h2>Data Pipeline</h2>
          <p>Event processing and exports</p>
        </div>
        <span class="status-pill">Operational</span>
      </article>

      <article class="status-card">
        <div>
          <h2>Dashboard</h2>
          <p>Customer reporting interface</p>
        </div>
        <span class="status-pill">Operational</span>
      </article>
    </section>

How does the service grid work?

  • The service-grid section groups the individual service states.
  • Each status-card names one part of the fictional API.
  • Each status-pill gives that service a compact health label.
  • Save index.html by pressing Ctrl+O.
  • Confirm the filename by pressing Enter.
  • Reload the local page in your browser.

You should now see Public API, Data Pipeline, and Dashboard listed below the hero. Each service has its own Operational label.

Missing a service card?

  • Confirm that the service-grid code sits between </header> and <footer>.
  • Check that every opening <article> has a matching </article>.

Help me find the missing HTML structure.

  • Exit GNU nano by pressing Ctrl+X.

✔️ Awesome, I've got everything!

Your index.html file now contains the complete status-page structure for this step.

ⓧ I'd like to double check the full code

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Northstar API Status</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="status-shell">
    <header class="hero">
      <p class="eyebrow">LIVE SERVICE STATUS</p>
      <h1>Northstar API</h1>
      <p class="summary">All systems operational.</p>
      <span class="overall-status">Operational</span>
    </header>

    <section class="service-grid" aria-label="Current service health">
      <article class="status-card">
        <div>
          <h2>Public API</h2>
          <p>Requests and authentication</p>
        </div>
        <span class="status-pill">Operational</span>
      </article>

      <article class="status-card">
        <div>
          <h2>Data Pipeline</h2>
          <p>Event processing and exports</p>
        </div>
        <span class="status-pill">Operational</span>
      </article>

      <article class="status-card">
        <div>
          <h2>Dashboard</h2>
          <p>Customer reporting interface</p>
        </div>
        <span class="status-pill">Operational</span>
      </article>
    </section>

    <footer>
      <p>Deployment: <strong>Manual draft</strong></p>
      <p>Hosting: GitHub Pages</p>
    </footer>
  </main>
</body>
</html>
Style and verify the status page

The HTML gives the page meaning. The stylesheet turns that structure into a focused status dashboard that remains readable on smaller screens.

  • Return to the Linux Mint XFCE Terminal.
  • Open style.css in GNU nano by running this command:
nano style.css

What does this command do?

GNU nano creates style.css in the repository. The link inside index.html makes these styles available to the page.

  • Create the dark page foundation by pasting this code into style.css:
:root {
  color-scheme: dark;
  font-family: Inter, ui-sans-serif, system-ui, sans-serif;
  background: #08111f;
  color: #e5eefb;
}

* {
  box-sizing: border-box;
}

body {
  min-height: 100vh;
  margin: 0;
  display: grid;
  place-items: center;
  background:
    radial-gradient(circle at top, #17345f 0, transparent 42%),
    #08111f;
}

.status-shell {
  width: min(900px, 92vw);
  padding: 3rem 0;
}

What does the foundation style?

  • The root rules set the dark colour scheme with the page typography.
  • The body uses a grid to centre the status page within the browser.
  • The status-shell limits the content width while preserving space on narrow screens.
  • Save style.css by pressing Ctrl+O.
  • Confirm the filename by pressing Enter.
  • Reload the local page in your browser.

You should see a dark blue background. The page content should sit in a centred column.

Still seeing a white page?

  • Confirm that style.css is saved beside index.html.
  • Check that the stylesheet link in index.html still uses style.css.

Help me connect my CSS file to the page.

  • Switch back to GNU nano.
  • Append the hero styles below the closing brace:
.hero {
  margin-bottom: 1.5rem;
}

.eyebrow {
  margin: 0 0 0.5rem;
  color: #93c5fd;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.16em;
}

h1 {
  margin: 0;
  font-size: clamp(2.4rem, 8vw, 5rem);
  line-height: 1;
}

.summary {
  color: #b8c6db;
  font-size: 1.1rem;
}

How does the hero gain hierarchy?

  • The eyebrow uses compact blue text to label the page's purpose.
  • The heading scales with the browser width while retaining a readable limit.
  • The summary uses a softer colour so the service name remains dominant.
  • Save style.css by pressing Ctrl+O.
  • Confirm the filename by pressing Enter.
  • Reload the local page in your browser.

You should see a larger Northstar API heading. The LIVE SERVICE STATUS label should appear above it in blue.

Hero styles not appearing?

  • Check that .hero and .eyebrow begin with a period.
  • Confirm that every selector block has a closing brace.

Help me fix the hero styling.

  • Switch back to GNU nano.
  • Append the badge and grid styles below the closing brace:
.overall-status,
.status-pill {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  color: #bbf7d0;
  background: #14532d;
  font-weight: 700;
}

.overall-status {
  padding: 0.55rem 0.9rem;
}

.service-grid {
  display: grid;
  gap: 1rem;
}

How do the health labels work?

  • The shared selector gives both health labels the same green treatment.
  • The large border radius creates the pill shape.
  • The service grid adds consistent space between the cards.
  • Save style.css by pressing Ctrl+O.
  • Confirm the filename by pressing Enter.
  • Reload the local page in your browser.

You should see green pill-shaped health labels. The service entries should have equal spacing between them.

Health labels still plain?

  • Confirm that the shared selector includes both .overall-status and .status-pill.
  • Check that the comma remains after .overall-status.

Help me fix the status badge selectors.

  • Switch back to GNU nano.
  • Append the service-card styles below the closing brace:
.status-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.25rem;
  border: 1px solid #34d399;
  border-radius: 1rem;
  background: rgba(15, 31, 54, 0.9);
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.25);
}

.status-card h2,
.status-card p {
  margin: 0;
}

.status-card p {
  margin-top: 0.35rem;
  color: #9fb0c8;
}

.status-pill {
  padding: 0.4rem 0.7rem;
  font-size: 0.82rem;
}

How do the cards become scannable?

  • Each card places its service details opposite the health label.
  • The green border separates each service from the dark background.
  • The softer description colour keeps the service name easy to find.
  • Save style.css by pressing Ctrl+O.
  • Confirm the filename by pressing Enter.
  • Reload the local page in your browser.

You should see three rounded cards with green borders. Each health label should sit on the right side of its card.

Cards not lining up?

  • Confirm that each article in index.html uses the status-card class.
  • Check that display: flex remains inside the .status-card block.

Help me repair the service-card layout.

  • Switch back to GNU nano.
  • Append the footer and responsive styles below the closing brace:
footer {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1.5rem;
  color: #8fa2bc;
  font-size: 0.9rem;
}

footer p {
  margin: 0;
}

@media (max-width: 600px) {
  .status-card,
  footer {
    align-items: flex-start;
    flex-direction: column;
  }
}

How does the page adapt?

  • The footer separates deployment details across the page width.
  • The media query changes cards into vertical layouts on narrow screens.
  • The same narrow-screen rule stacks the footer details.
  • Save style.css by pressing Ctrl+O.
  • Confirm the filename by pressing Enter.
  • Exit GNU nano by pressing Ctrl+X.

✔️ Awesome, I've got everything!

Your style.css file now contains the complete visual design for this step.

ⓧ I'd like to double check the full code

:root {
  color-scheme: dark;
  font-family: Inter, ui-sans-serif, system-ui, sans-serif;
  background: #08111f;
  color: #e5eefb;
}

* {
  box-sizing: border-box;
}

body {
  min-height: 100vh;
  margin: 0;
  display: grid;
  place-items: center;
  background:
    radial-gradient(circle at top, #17345f 0, transparent 42%),
    #08111f;
}

.status-shell {
  width: min(900px, 92vw);
  padding: 3rem 0;
}

.hero {
  margin-bottom: 1.5rem;
}

.eyebrow {
  margin: 0 0 0.5rem;
  color: #93c5fd;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.16em;
}

h1 {
  margin: 0;
  font-size: clamp(2.4rem, 8vw, 5rem);
  line-height: 1;
}

.summary {
  color: #b8c6db;
  font-size: 1.1rem;
}

.overall-status,
.status-pill {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  color: #bbf7d0;
  background: #14532d;
  font-weight: 700;
}

.overall-status {
  padding: 0.55rem 0.9rem;
}

.service-grid {
  display: grid;
  gap: 1rem;
}

.status-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.25rem;
  border: 1px solid #34d399;
  border-radius: 1rem;
  background: rgba(15, 31, 54, 0.9);
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.25);
}

.status-card h2,
.status-card p {
  margin: 0;
}

.status-card p {
  margin-top: 0.35rem;
  color: #9fb0c8;
}

.status-pill {
  padding: 0.4rem 0.7rem;
  font-size: 0.82rem;
}

footer {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1.5rem;
  color: #8fa2bc;
  font-size: 0.9rem;
}

footer p {
  margin: 0;
}

@media (max-width: 600px) {
  .status-card,
  footer {
    align-items: flex-start;
    flex-direction: column;
  }
}

Before you check the finished page, which visual details do you expect to make the service health easiest to scan?

  • Reload ~/linux-status-page/index.html in your browser.

You should see the Northstar API heading above an Operational badge. Three dark service cards should appear below with green borders and health labels.

That local preview is working. The footer should show Manual draft above the GitHub Pages hosting label.

Finished page not matching?

  • Reload the browser after confirming that both files are saved.
  • Check that index.html and style.css are both inside ~/linux-status-page.
  • Compare both files with the full-code tabs above to find a missing brace or tag.

Help me debug the finished local status page.

Your status page now works locally as a complete baby version. Next up, you will push it to GitHub and uncover the missing deployment layer.

Push the Status Page

Your Northstar API page now works locally. Its Operational badge and three service cards prove the browser can render the finished design.

A Git repository preserves the page as a commit. You will push that history to GitHub before testing its expected public address.

In this step, get ready to:
  • Create an empty public repository for the status page.
  • Commit the local page files and push them to GitHub.
  • Test whether the expected public address serves the page.
Create the public repository

This repository is public, so every committed file is visible to anyone. Your project contains only the status page files from the previous step.

  • On GitHub, click New repository.
  • Choose your GitHub account under Owner.
  • Enter linux-status-page in the Repository name field.
  • Select Public under visibility.
  • Leave the repository's README choice unselected.
  • Leave the repository's .gitignore choice unselected.
  • Leave the repository's license choice unselected.
  • Click Create repository.

You will see the empty repository's Quick Setup section. This page provides the address that connects your local repository to GitHub.

  • Select SSH in the Quick Setup section.
  • Copy the SSH remote URL.

Why Start With an Empty Repository?

Your local repository already contains the project files and history. Adding starter files on GitHub could introduce a separate history that conflicts with the first push.

Commit and push the page

Your files are saved on disk, but Git has not recorded them as a project milestone. A commit captures their current state with a message that explains what changed.

  • Stage the current page files and record the first commit by running these commands:
git add .
git commit -m "Build local status page"

What Do These Commands Do?

  • The first command stages every changed file in ~/linux-status-page for the next commit.
  • The second command records the staged files with the message Build local status page.
  • Read the commit summary in the terminal.

You should see a new commit named Build local status page. The summary should include index.html and style.css.

Commit Missing a File?

  • Confirm the terminal is still working in ~/linux-status-page.
  • Confirm index.html and style.css were saved before you staged them.

Help me diagnose why my local status page files were not included in the Git commit.

The commit currently exists only on your Linux Mint machine. A remote named origin gives Git the SSH destination for the public repository.

  • Replace REMOTE-URL in the command below with the SSH URL on your clipboard.
  • Connect the local repository to GitHub and display the configured remote by running these commands:
git remote add origin REMOTE-URL
git remote -v

What Do These Commands Do?

  • The first command saves the GitHub repository address under the short name origin.
  • The second command displays the saved destination for fetching and pushing.
  • Compare the displayed fetch and push URLs with the SSH URL from GitHub.

Both origin entries should point to the SSH URL for linux-status-page.

Remote URL Look Wrong?

  • Check that you replaced REMOTE-URL with the copied repository address.
  • Confirm the copied address uses the SSH option from Quick Setup.

Help me correct the origin remote for my linux-status-page repository.

Before you push, predict whether the commit will stay local or appear in the public GitHub repository.

  • Send the main branch to GitHub by running this command:
git push -u origin main

What Does This Command Do?

The command sends the local main branch to origin. The -u flag records the upstream connection for future pushes.

You should see Git transfer the commit and associate the local main branch with the remote branch.

Push Not Reaching GitHub?

  • Confirm origin points to the SSH URL for your repository.
  • Check that your public key remains added under GitHub's SSH and GPG keys settings.

Help me troubleshoot why my authenticated SSH push to the linux-status-page repository is failing.

  • Switch back to the linux-status-page repository in your browser.
  • Refresh the repository page.

That push worked. Your public repository now shows index.html and style.css from the local commit.

Test the public site address

GitHub now holds your source files. The next check tests whether storing those files also delivers the status page as a website.

Before you visit the address, predict whether a successful push also made the page public.

  • Visit https://YOUR-USERNAME.github.io/linux-status-page/ in your browser using your GitHub username in place of YOUR-USERNAME.

The Northstar API status page is unavailable at this address. This is the intended shortfall.

The repository stores your source files. No Pages deployment has been configured to publish them.

What Did This Prove?

A GitHub repository records files and commit history. GitHub Pages needs a configured publishing process before it can serve those files as a website.

A CI/CD pipeline turns a code change into a repeatable delivery process. That missing bridge explains why the repository is visible while the site remains unavailable.

Your source is now safely committed and pushed to GitHub. Next, you will use GitHub Actions to turn each push into a live GitHub Pages deployment.

Automate the Pages Deployment

You have stored your status page in a public repository on GitHub. The missing website exposed the delivery gap between saving source code and publishing it.

In this step, you will use GitHub Actions to send each push to main through a deployment workflow. GitHub Pages will publish the resulting site at your public URL.

In this step, get ready to:
  • Select GitHub Actions as the GitHub Pages deployment source.
  • Create a workflow that publishes the status page after each push to main.
  • Prove that a content update reaches the public website automatically.
Choose GitHub Actions as the Pages source

GitHub Pages needs a publishing source before it can serve your site. Selecting GitHub Actions connects Pages to the deployment workflow you create next.

  • Return to the public linux-status-page repository on GitHub.
  • Click Settings in the repository navigation.
  • Select Pages in the left sidebar.
  • Find the Build and deployment section.
  • Open the Source menu.
  • Select GitHub Actions.

The Pages settings now show GitHub Actions as the source. Your repository is ready to accept a deployment artifact from a workflow.

Create the workflow and launch the first run

A YAML file inside .github/workflows defines when the deployment starts. It also defines the permissions and steps used to publish the page.

  • Create .github/workflows inside ~/linux-status-page by running these commands:
mkdir -p .github/workflows
nano .github/workflows/deploy.yml

What Do These Commands Do?

The first command creates the nested workflow directory. The -p option creates any missing parent directories.

The second command opens deploy.yml in GNU nano. GNU nano creates the file when you save it.

  • Paste the deployment workflow into GNU nano:
name: Deploy status page

on:
  push:
    branches:
      - main

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Checkout
        uses: actions/checkout@v7.0.1
      - name: Configure Pages
        uses: actions/configure-pages@v6.0.0
      - name: Upload Pages artifact
        uses: actions/upload-pages-artifact@v5.0.0
        with:
          path: '.'
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v5.0.0

What Does This Workflow Do?

  • The push trigger starts the workflow when a commit reaches main.
  • The contents: read permission lets the job read the repository files.
  • The pages: write permission authorizes publication to GitHub Pages.
  • The id-token: write permission lets the deployment request an identity token.
  • The ubuntu-latest label assigns the job to a hosted runner.
  • The checkout step copies the triggering repository onto the runner.
  • The upload step packages the static files as a deployment artifact.
  • The final step publishes that artifact to the github-pages environment.
  • Save .github/workflows/deploy.yml using GNU nano's save command.
  • Exit GNU nano to return to the terminal.

✔️ Awesome, I've got everything!

Your deployment workflow is ready. Double-check that deploy.yml is saved before you push it.

ⓧ I'd like to double check the full code

name: Deploy status page

on:
  push:
    branches:
      - main

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Checkout
        uses: actions/checkout@v7.0.1
      - name: Configure Pages
        uses: actions/configure-pages@v6.0.0
      - name: Upload Pages artifact
        uses: actions/upload-pages-artifact@v5.0.0
        with:
          path: '.'
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v5.0.0
  • Commit the deployment workflow to main by running these commands:
git add .
git commit -m "Automate Pages deployment"
git push

What Does This Push Start?

The commit records .github/workflows/deploy.yml in the repository. The push matches the workflow trigger because it reaches main.

GitHub assigns the deployment job to a hosted runner. The runner packages the page before publishing it to GitHub Pages.

The first publication can take up to 10 minutes after the push. A short wait is normal while GitHub Pages processes the deployment artifact.

  • Return to the linux-status-page repository on GitHub.
  • Click the Actions tab.
  • Select Deploy status page from the workflow list.

Before you open the latest run, predict whether GitHub recognized the new workflow after this push.

  • Open the latest workflow run.

You should see the deployment finish with a green check. That result proves the repository can package and publish the status page.

Is the First Deployment Failing?

  • Check that the workflow file is stored at .github/workflows/deploy.yml.
  • Compare the YAML indentation with the full-code tab above.
  • Confirm that GitHub Actions remains selected as the Pages source.

Help me troubleshoot the failed Pages deployment.

Prove every push redeploys the page

The first run proves the pipeline can publish the current files. A second content-only commit proves that continuous deployment carries later changes to the live site.

  • Switch back to the terminal from earlier.
  • Open index.html with GNU nano by running this command:
nano index.html

Why Edit a Visible Label?

GNU nano opens the existing page from ~/linux-status-page. Changing a visible footer label gives you a clear signal when the new commit reaches the public site.

  • Find this line in the footer:
      <p>Deployment: <strong>Manual draft</strong></p>

What Does the Current Label Show?

The existing label describes the manual version you pushed earlier. It gives the automatic deployment a visible before state.

  • Replace the footer line with this automated deployment label:
      <p>Deployment: <strong>Automated by GitHub Actions</strong></p>

What Changed?

The footer now identifies GitHub Actions as the deployment method. Seeing this exact text on the public page proves the second commit was published.

  • Save index.html using GNU nano's save command.
  • Exit GNU nano to return to the terminal.

✔️ Awesome, I've got everything!

Your footer is ready. Double-check that index.html is saved before you push the update.

ⓧ I'd like to double check the full code

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Northstar API Status</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="status-shell">
    <header class="hero">
      <p class="eyebrow">LIVE SERVICE STATUS</p>
      <h1>Northstar API</h1>
      <p class="summary">All systems operational.</p>
      <span class="overall-status">Operational</span>
    </header>

    <section class="service-grid" aria-label="Current service health">
      <article class="status-card">
        <div>
          <h2>Public API</h2>
          <p>Requests and authentication</p>
        </div>
        <span class="status-pill">Operational</span>
      </article>

      <article class="status-card">
        <div>
          <h2>Data Pipeline</h2>
          <p>Event processing and exports</p>
        </div>
        <span class="status-pill">Operational</span>
      </article>

      <article class="status-card">
        <div>
          <h2>Dashboard</h2>
          <p>Customer reporting interface</p>
        </div>
        <span class="status-pill">Operational</span>
      </article>
    </section>

    <footer>
      <p>Deployment: <strong>Automated by GitHub Actions</strong></p>
      <p>Hosting: GitHub Pages</p>
    </footer>
  </main>
</body>
</html>

Before you push, consider whether a content-only commit starts another deployment.

  • Commit the footer update to main by running these commands:
git add .
git commit -m "Automate Pages deployment"
git push

Why Does This Trigger Another Run?

The workflow listens for every push to main. This content-only commit matches that trigger and starts the deployment process again.

The updated page can take a few minutes to reach the public URL. GitHub Pages is publishing the new artifact during this wait.

  • Return to the repository's Actions tab.
  • Open the newest Deploy status page run.
  • Confirm that the run finishes with a green check.
  • Refresh https://YOUR-USERNAME.github.io/linux-status-page/ in your browser.

You should see the Northstar API page with Automated by GitHub Actions in the footer. The service cards retain their #34d399 green borders.

Still Seeing Manual Draft?

  • Confirm that the newest workflow run has a green check before refreshing the site.
  • Allow up to 10 minutes for GitHub Pages to publish the latest artifact.
  • Check that the committed footer line in index.html contains Automated by GitHub Actions.

Help me find why the live Pages site still shows the old footer.

You closed the delivery gap. Each push to main can now move your status page from the terminal to a public website.

Secret mission

Run Deployments Only for Site Changes

Your deployment works after every push to main. This mission adds path filters so documentation-only commits stay quiet while site changes still reach the live page.

Clean Up Your Resources

Clean Up Your Resources

Choose whether to keep your GitHub Pages site live, pause new deployments, or remove the project entirely. This project costs $0 on the prescribed public repository path with a standard GitHub-hosted runner.

Resources you used:

  • One local Git repository at ~/linux-status-page.
  • One public GitHub repository named linux-status-page.
  • One GitHub Actions workflow named Deploy status page with its deployment history.
  • One public GitHub Pages site served from the repository.

Keep everything running

Keep this option if you want the status page to stay live. Your public repository can continue using standard GitHub-hosted runners at no cost.

  • Leave the public linux-status-page repository unchanged.
  • Keep the Deploy status page workflow enabled.
  • Continue using the live site to verify relevant changes pushed to main.

Pause - I'll come back to this later

Pause the workflow to stop new deployment runs while preserving the repository. Your existing site remains available until you return.

  • Return to the linux-status-page repository on GitHub.
  • Select the Actions tab.
  • Select Deploy status page from the workflow list.
  • Open the workflow's options menu.
  • Choose Disable workflow.

Future pushes stop triggering this workflow. The current GitHub Pages site stays online.

Resume Deployments Later

The same workflow menu lets you enable deployments again when you return.

Delete - I don't want to use this again

Deleting the repository is permanent. The local folder stays separate until you remove it with the command below, so you can stop before that final action.

  • Return to the public linux-status-page repository on GitHub.
  • Select Settings.
  • Select General.
  • Scroll to Danger Zone.
  • Select Delete this repository.
  • Read the repository deletion warnings.
  • Enter linux-status-page when GitHub asks for the repository name.
  • Confirm the repository deletion.

This removes the public repository that stores the workflow and supplies the Pages deployment source. The deployment history and live site no longer remain available from that repository.

  • Remove the local ~/linux-status-page folder by running this command:
rm -rf ~/linux-status-page

What Does This Command Remove?

The command permanently removes only the ~/linux-status-page folder named in the path. Your remote GitHub repository is handled by the separate deletion steps above.

  • Confirm the local folder is gone by running this command:
ls -al ~

What Should I See?

The command lists the contents of your home folder. You should no longer see linux-status-page in the output.

Still See the Local Folder?

  • Check that the deletion path is exactly ~/linux-status-page.
  • Get help before trying another deletion command if your terminal reports a permissions problem.

Nice Work!

Nice Work!

You did it! Your Northstar API status page is live on GitHub Pages. Relevant pushes to main now trigger GitHub Actions deployments automatically.

What you learned:

  • Created a styled service-status page that displays the health of the Northstar API. Its responsive layout shows three service cards with clear operational states.
  • Configured Git author identity for traceable commits. Connected Linux Mint to GitHub through SSH authentication.
  • Built a least-privilege workflow that packages the status page for GitHub Pages. Proved continuous deployment when the live footer changed to Automated by GitHub Actions after a second push.
  • Secret Mission: Restricted deployments with path filters. A commit that only changed README.md skipped the workflow. A style.css change still triggered a deployment that turned the live card borders cyan.

Ready to quiz yourself?