From 12b7de5ca751398e26ad70748f710e57d28541a6 Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Wed, 7 Jan 2026 15:34:37 -0700 Subject: [PATCH 1/6] rename ci/cd flows --- .github/workflows/{publish.yml => app-cd.yml} | 0 .github/workflows/{ci.yml => app-ci.yml} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{publish.yml => app-cd.yml} (100%) rename .github/workflows/{ci.yml => app-ci.yml} (98%) diff --git a/.github/workflows/publish.yml b/.github/workflows/app-cd.yml similarity index 100% rename from .github/workflows/publish.yml rename to .github/workflows/app-cd.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/app-ci.yml similarity index 98% rename from .github/workflows/ci.yml rename to .github/workflows/app-ci.yml index cbd2aa1..7d111a4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/app-ci.yml @@ -1,4 +1,4 @@ -name: Continuous Integration +name: Merge Checks (CI) on: pull_request: From 3dd9c94ff8f85e0559121947261dc39b8dc74ffd Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Wed, 7 Jan 2026 15:34:48 -0700 Subject: [PATCH 2/6] readme tweaks before big additions --- README.md | 2 +- app/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f422fd9..6d989ec 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # GitHub Actions Demo > [!NOTE] -> See ./app/README.md for a more specific readme telling you how the code in this repo works +> See ./app/README.md for a more specific readme telling you how the code in this repo works. This document itself is more of an instruction manual for the skill-a-thon. For an interactive experience, this repo is set up so that you can fork it to your personal GitHub accounts and practice pushing, opening pull-requests, and otherwise using the GitHub Action Workflows. I'll demonstrate how things work while I present. Maybe I'll also add in-depth explanations to the repo itself, if I have time. diff --git a/app/README.md b/app/README.md index 87fc9a0..8acc45b 100644 --- a/app/README.md +++ b/app/README.md @@ -1,7 +1,7 @@ # A Website This is a website. It uses a [Fastify](https://fastify.dev/) backend, running on [Node.js](https://nodejs.org/en), on the backend to serve raw HTML. -> [!NOTE] +> [!TIP] > The BYU Office of IT and Lucid Software use Fastify in one way or another, alongside other big names like Mercedes. Industry leaders like the Linux Foundation recommend Fastify for Node.js web servers. ## Setup From eb7ba163a32636059ac95dbfe3a4ed27b90c2d3c Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Wed, 7 Jan 2026 15:34:56 -0700 Subject: [PATCH 3/6] remove unneeded docker-compose --- .github/workflows/app-cd.yml | 75 +++++++++++++++++++++++------------- docker-compose.yml | 6 --- 2 files changed, 48 insertions(+), 33 deletions(-) delete mode 100644 docker-compose.yml diff --git a/.github/workflows/app-cd.yml b/.github/workflows/app-cd.yml index 278b669..0d03d10 100644 --- a/.github/workflows/app-cd.yml +++ b/.github/workflows/app-cd.yml @@ -5,10 +5,10 @@ on: push: branches: [main] paths-ignore: - - 'README.md' + - '**/*.md' - '.gitignore' - - 'docker-compose.yml' - - '.github/workflows/ci.yml' + - '.github/workflows/app-ci.yml' + - '.github/workflows/uptime-check.yml' env: node_version: "22.x" @@ -38,28 +38,49 @@ jobs: working-directory: app run: npm run build - build_and_deploy: - name: Push to Docker Hub - runs-on: ubuntu-latest - needs: [build] - steps: - - name: Check out - uses: actions/checkout@v4 - - - name: Log in to Docker Hub - uses: docker/login-action@v3 +# If you implement the Docker Publish step (see below), you can probably remove these next two steps +# These are just here to have a deploy-esque thing happen that doesn't require credentials + - name: Create deployment package + run: | + cd app + zip -r ../app-deployment.zip dist/ package.json package-lock.json + cd .. + echo "Created mock deployment package: app-deployment.zip" + - name: Upload deployment artifact + uses: actions/upload-artifact@v4 with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v5 - with: - images: YOUR_ACCOUNT_HERE/YOUR_IMAGE_ID_HERE - - name: Build and push Docker image - uses: docker/build-push-action@v6 - with: - context: app - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + name: app-deployment + path: app-deployment.zip + retention-days: 7 + +# Uncomment this step if you want to try uploading the app to Docker Hub +# However, you will need to set up a Docker Hub account and repository first + + # build_and_deploy: + # name: Push to Docker Hub + # runs-on: ubuntu-latest + # needs: [build] + # steps: + # - name: Check out + # uses: actions/checkout@v4 + # - name: Log in to Docker Hub + # uses: docker/login-action@v3 + # with: + # # Add these secrets to your github repository if you want to try this step + # # https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets + # username: ${{ secrets.DOCKER_USERNAME }} + # password: ${{ secrets.DOCKER_PASSWORD }} + # - name: Extract metadata (tags, labels) for Docker + # id: meta + # uses: docker/metadata-action@v5 + # with: + # # Change these two things if you want to try this step + # # These are values for your Docker Hub Repo/Account, not GitHub + # images: YOUR_ACCOUNT_HERE/YOUR_IMAGE_ID_HERE + # - name: Build and push Docker image + # uses: docker/build-push-action@v6 + # with: + # context: app + # push: true + # tags: ${{ steps.meta.outputs.tags }} + # labels: ${{ steps.meta.outputs.labels }} diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 725fb5b..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,6 +0,0 @@ -version: '3' -services: - app: - build: ./app - ports: - - '3000:3000' From f766c05aa2ea3f7ca0c31f8678ff1ba69b2933fa Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Wed, 7 Jan 2026 15:35:29 -0700 Subject: [PATCH 4/6] first pr --- .github/workflows/app-ci.yml | 24 +----------------------- .github/workflows/uptime-check.yml | 30 ++++++++++++++++++++++++++++++ app/.gitignore | 2 -- app/public/index.html | 2 +- 4 files changed, 32 insertions(+), 26 deletions(-) create mode 100644 .github/workflows/uptime-check.yml delete mode 100644 app/.gitignore diff --git a/.github/workflows/app-ci.yml b/.github/workflows/app-ci.yml index 7d111a4..57ceb09 100644 --- a/.github/workflows/app-ci.yml +++ b/.github/workflows/app-ci.yml @@ -15,7 +15,7 @@ env: jobs: test: - name: Build & Test + name: Lint, Build & Test runs-on: ubuntu-latest timeout-minutes: 3 steps: @@ -44,28 +44,6 @@ jobs: working-directory: app run: npm run build - lint: - name: Lint - runs-on: ubuntu-latest - timeout-minutes: 3 - steps: - - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.node_version }} - cache: npm - cache-dependency-path: '**/package-lock.json' - - - name: npm ci - working-directory: app - run: npm ci --prefer-offline - - - name: npm lint - working-directory: app - run: npm run lint - docker: name: Docker Build runs-on: ubuntu-latest diff --git a/.github/workflows/uptime-check.yml b/.github/workflows/uptime-check.yml new file mode 100644 index 0000000..e0eff01 --- /dev/null +++ b/.github/workflows/uptime-check.yml @@ -0,0 +1,30 @@ +name: Uptime Check + +on: + workflow_dispatch: + # schedule: + # - cron: '*/5 * * * *' # Every 5 minutes + +jobs: + check: + name: Check Website Status + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Ping website + id: ping + run: | + if curl --fail --silent --head --max-time 10 https://wikipedia.org > /dev/null 2>&1; then + echo "status=up" >> $GITHUB_OUTPUT + echo "Website is up!" + else + echo "status=down" >> $GITHUB_OUTPUT + echo "Website is down!" + fi + + - name: Send Discord notification + if: steps.ping.outputs.status == 'down' + run: | + curl -H "Content-Type: application/json" \ + -d "{\"content\": \"🚨 **Website Alert** 🚨\n\nWebsite \`https://wikipedia.org\` is currently **DOWN**.\n\nTime: $(date -u '+%Y-%m-%d %H:%M:%S UTC')\nWorkflow: ${{ github.workflow }}\nRun: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\"}" \ + ${{ secrets.DISCORD_WEBHOOK_URL }} diff --git a/app/.gitignore b/app/.gitignore deleted file mode 100644 index 87820e4..0000000 --- a/app/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -app/node_modules/ -app/dist/ diff --git a/app/public/index.html b/app/public/index.html index f07b2cd..78bc091 100644 --- a/app/public/index.html +++ b/app/public/index.html @@ -11,6 +11,6 @@

Hello World!

-

I dare you to go to /rickroll

+ From a19be2a2e13d4e1af6172e826bb542bee41197a7 Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Wed, 7 Jan 2026 16:41:37 -0700 Subject: [PATCH 5/6] remove steps so people can re-add them --- .github/workflows/app-ci.yml | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/.github/workflows/app-ci.yml b/.github/workflows/app-ci.yml index 57ceb09..671ca7c 100644 --- a/.github/workflows/app-ci.yml +++ b/.github/workflows/app-ci.yml @@ -15,7 +15,7 @@ env: jobs: test: - name: Lint, Build & Test + name: Test runs-on: ubuntu-latest timeout-minutes: 3 steps: @@ -32,31 +32,6 @@ jobs: working-directory: app run: npm ci --prefer-offline - - name: npm lint - working-directory: app - run: npm run lint - - name: npm run test working-directory: app run: npm run test - - - name: npm run build - working-directory: app - run: npm run build - - docker: - name: Docker Build - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - uses: actions/checkout@v4 - - - name: Setup Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: docker build - uses: docker/build-push-action@v6 - with: - context: app - cache-from: type=gha - cache-to: type=gha,mode=max From 1acd1e332e89f8407c00dca5defa8e0744739ada Mon Sep 17 00:00:00 2001 From: Caleb Hill Date: Thu, 8 Jan 2026 11:43:11 -0700 Subject: [PATCH 6/6] test workflows --- .github/workflows/app-cd.yml | 58 +++++++++++++++--------------- .github/workflows/app-ci.yml | 18 ++++++++++ .github/workflows/uptime-check.yml | 14 ++++++-- 3 files changed, 58 insertions(+), 32 deletions(-) diff --git a/.github/workflows/app-cd.yml b/.github/workflows/app-cd.yml index 0d03d10..dbdf2a3 100644 --- a/.github/workflows/app-cd.yml +++ b/.github/workflows/app-cd.yml @@ -55,32 +55,32 @@ jobs: # Uncomment this step if you want to try uploading the app to Docker Hub # However, you will need to set up a Docker Hub account and repository first - - # build_and_deploy: - # name: Push to Docker Hub - # runs-on: ubuntu-latest - # needs: [build] - # steps: - # - name: Check out - # uses: actions/checkout@v4 - # - name: Log in to Docker Hub - # uses: docker/login-action@v3 - # with: - # # Add these secrets to your github repository if you want to try this step - # # https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets - # username: ${{ secrets.DOCKER_USERNAME }} - # password: ${{ secrets.DOCKER_PASSWORD }} - # - name: Extract metadata (tags, labels) for Docker - # id: meta - # uses: docker/metadata-action@v5 - # with: - # # Change these two things if you want to try this step - # # These are values for your Docker Hub Repo/Account, not GitHub - # images: YOUR_ACCOUNT_HERE/YOUR_IMAGE_ID_HERE - # - name: Build and push Docker image - # uses: docker/build-push-action@v6 - # with: - # context: app - # push: true - # tags: ${{ steps.meta.outputs.tags }} - # labels: ${{ steps.meta.outputs.labels }} +# TODO RE_COMMENT THESE LINES BELOW + build_and_deploy: + name: Push to Docker Hub + runs-on: ubuntu-latest + needs: [build] + steps: + - name: Check out + uses: actions/checkout@v4 + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + # Add these secrets to your github repository if you want to try this step + # https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + # Change these two things if you want to try this step + # These are values for your Docker Hub Repo/Account, not GitHub + images: YOUR_ACCOUNT_HERE/YOUR_IMAGE_ID_HERE + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: app + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/app-ci.yml b/.github/workflows/app-ci.yml index 671ca7c..7e65ea3 100644 --- a/.github/workflows/app-ci.yml +++ b/.github/workflows/app-ci.yml @@ -35,3 +35,21 @@ jobs: - name: npm run test working-directory: app run: npm run test + +# Make sure the Dockerfile builds properly as well, since we will likely deploy with Docker + docker: + name: Docker Build + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: docker build + uses: docker/build-push-action@v6 + with: + context: app + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/uptime-check.yml b/.github/workflows/uptime-check.yml index e0eff01..62f29ed 100644 --- a/.github/workflows/uptime-check.yml +++ b/.github/workflows/uptime-check.yml @@ -10,11 +10,13 @@ jobs: name: Check Website Status runs-on: ubuntu-latest timeout-minutes: 5 + env: + WEBSITE_URL: https://wikipedia.org steps: - name: Ping website id: ping run: | - if curl --fail --silent --head --max-time 10 https://wikipedia.org > /dev/null 2>&1; then + if curl --fail --silent --head --max-time 10 ${{ env.WEBSITE_URL }} > /dev/null 2>&1; then echo "status=up" >> $GITHUB_OUTPUT echo "Website is up!" else @@ -22,9 +24,15 @@ jobs: echo "Website is down!" fi +# Uncomment this step if you have a discord webhook URL (add it to your repository secrets) +# for a channel that you want to send messages to. To see it actually send messages, I've inverted the condition +# so it actually notifies if the website is up, not down. In real use, we'd obviously want the opposite of that. +# TODO RE_COMMENT THESE LINES BELOW - name: Send Discord notification - if: steps.ping.outputs.status == 'down' + if: steps.ping.outputs.status == 'up' + # SWITCH TO THIS LINE FOR DOWNTIME DETECTION + # if: steps.ping.outputs.status == 'down' run: | curl -H "Content-Type: application/json" \ - -d "{\"content\": \"🚨 **Website Alert** 🚨\n\nWebsite \`https://wikipedia.org\` is currently **DOWN**.\n\nTime: $(date -u '+%Y-%m-%d %H:%M:%S UTC')\nWorkflow: ${{ github.workflow }}\nRun: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\"}" \ + -d "{\"content\": \"**Website Alert**\n\nWebsite \`${{ env.WEBSITE_URL }}\` is currently **DOWN**.\n\nTime: $(date -u '+%Y-%m-%d %H:%M:%S UTC')\nWorkflow: ${{ github.workflow }}\nRun: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\"}" \ ${{ secrets.DISCORD_WEBHOOK_URL }}