diff --git a/.github/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index fff844d..0000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-version: 2
-updates:
- - package-ecosystem: "github-actions"
- directory: "/"
- schedule:
- interval: "monthly"
-
- - package-ecosystem: "devcontainers"
- directory: "/"
- schedule:
- interval: "monthly"
diff --git a/.github/steps/-step.txt b/.github/steps/-step.txt
deleted file mode 100644
index 573541a..0000000
--- a/.github/steps/-step.txt
+++ /dev/null
@@ -1 +0,0 @@
-0
diff --git a/.github/steps/0-welcome.md b/.github/steps/0-welcome.md
deleted file mode 100644
index 9ff13a5..0000000
--- a/.github/steps/0-welcome.md
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/.github/steps/1-first-codespace.md b/.github/steps/1-first-codespace.md
index f517a05..8836bef 100644
--- a/.github/steps/1-first-codespace.md
+++ b/.github/steps/1-first-codespace.md
@@ -1,64 +1,92 @@
-
+## Step 1: Start a codespace and push some code
-## Step 1: Create your first codespace and push code
+### What's the big deal about Codespaces?
-_Welcome to "Develop code using GitHub Codespaces and Visual Studio Code"! :wave:_
+A **codespace** is a development environment hosted in the cloud, defined by configuration files in your repository. This creates a repeatable development environment tailored specifically to the project that simplifies developer onboarding and avoids the famous phrase "It works on my machine!" 😎
-**What's the big deal about using a codespace for software development?** A codespace is a development environment that's hosted in the cloud. You can customize your project for GitHub Codespaces by committing configuration files to your repository (also known as configuration-as-code), which creates a repeatable codespace configuration for all users of your project. Each codespace you create is hosted by GitHub in a Docker container that runs on a virtual machine. You can choose the type of machine you want to use depending on the resources you need.
+Each codespace follows the [Dev Container specification](https://containers.dev/implementors/spec/) and is hosted by GitHub as a [Docker container](https://code.visualstudio.com/docs/devcontainers/containers).
-GitHub offers a range of features to help your development team customize a codespace to reach peak configuration and performance needs. For example, you can:
+But don't worry! You don't need to know Docker or even have it installed on your machine!
-- Create a codespace from your repository.
-- Push code from the codespace to your repository.
-- Use VS Code to develop code.
-- Customize the codespace with custom images.
-- Manage the codespace.
+> [!TIP]
+> Since the Dev Container configuration is part of the repository, you can also use it locally with your own Docker host. Nice!
-To begin developing using GitHub Codespaces, you can create a codespace from a template or from any branch or commit in a repository. When you create a codespace from a template, you can start from a blank template or choose a template suitable for the work you're doing.
+A Codespace has several advantages/features compared to local development. To name a few:
-### :keyboard: Activity: Start a codespace
+- Start a codespace directly from the repository page.
+- Develop in the browser. No IDE installation required.
+ - Option to use a local install of VS Code to link to the remote Codespace.
+- Preconfigure everything you need to run the project:
+ - Add **[features](https://containers.dev/features)** to install common development needs.
+ - Run scripts at various steps of the codespace lifecycle _(e.g install python/npm packages)_.
+ - Setup VS Code settings and extensions to match the project needs.
+- Fast internet access (since the container is in the datacenter).
-**We recommend opening another browser tab to work through the following activities so you can keep these instructions open for reference.**
+> [!TIP]
+> Codespaces are even useful in short-lived situations like reviewing a pull request. No need to verify you have the right setup to test out the incoming code changes.
-1. Start from the landing page of your repository.
-1. Click the green **Code** button located in the middle of the page.
-1. Select the **Codespaces** tab in the box that pops up and then click the **Create codespace on main** button.
+Let's get started! We'll start up a Codespace, run the application, make a change, and push it. Like normal development! 🤓
- > Wait about 2 minutes for the codespace to spin itself up.
- > **Note**: It's a virtual machine spinning up in the background.
+### ⌨️ Activity: Start a codespace
-1. Verify your codespace is running. The browser should contain a VS Code web-based editor and a terminal should be present such as the below:
- 
+1. Open a second tab and navigate to this repository. Ensure you are on the **Code** tab.
-### :keyboard: Activity: Push code to your repository from the codespace
+1. Above the files list on the right, click the green **<> Code** button.
-1. From inside the codespace in the VS Code explorer window, select the `index.html` file.
-1. Replace the **h1** header with the below:
+
- ```html
-
Here's a recap of all the tasks you've accomplished in your repository:
- You learned how to create a codespace and push code to your repository from the codespace.
-- You learned how to use custom images in your codespace.
-- You learned how to customize your codespace.
-- You learned how to personalize your codespace.
+- You learned how to use custom images, features, extensions, and scripts in your codespace.
+- You learned how to test run it like an onboarding developer.
### Additional learning and resources
@@ -26,8 +18,6 @@ Here's a recap of all the tasks you've accomplished in your repository:
### What's next?
-- Learn more about securing your supply chain by reading: [GitHub Codespaces overview](https://docs.github.com/en/codespaces/overview).
-- [We'd love to hear what you thought of this course](https://github.com/orgs/skills/discussions/categories/code-with-codespaces).
-- [Learn another GitHub skill](https://github.com/skills).
+- [Take another GitHub Skill exercise](https://github.com/skills).
- [Read the Get started with GitHub docs](https://docs.github.com/en/get-started).
- To find projects to contribute to, check out [GitHub Explore](https://github.com/explore).
diff --git a/.github/workflows/0-start-exercise.yml b/.github/workflows/0-start-exercise.yml
new file mode 100644
index 0000000..4fb47ea
--- /dev/null
+++ b/.github/workflows/0-start-exercise.yml
@@ -0,0 +1,72 @@
+name: Step 0
+
+on:
+ push:
+ branches:
+ - main
+
+permissions:
+ contents: write
+ actions: write
+ issues: write
+
+env:
+ STEP_1_FILE: ".github/steps/1-first-codespace.md"
+
+jobs:
+ start_exercise:
+ if: |
+ !github.event.repository.is_template
+ name: Start Exercise
+ uses: skills/exercise-toolkit/.github/workflows/start-exercise.yml@v0.5.0
+ with:
+ exercise-title: "Code with Codespaces"
+ intro-message: "Let's create a pre-configured environment to simplify development!"
+
+ post_next_step_content:
+ name: Post next step content
+ runs-on: ubuntu-latest
+ needs: [start_exercise]
+ env:
+ ISSUE_URL: ${{ needs.start_exercise.outputs.issue-url }}
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Get response templates
+ uses: actions/checkout@v4
+ with:
+ repository: skills/exercise-toolkit
+ path: exercise-toolkit
+ ref: v0.5.0
+
+ - name: Build comment - add step content
+ id: build-comment
+ uses: skills/action-text-variables@v2
+ with:
+ template-file: ${{ env.STEP_1_FILE }}
+ template-vars: |
+ login: ${{ github.actor }}
+ full_repo_name: ${{ github.repository }}
+
+ - name: Create comment - add step content
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body "$ISSUE_BODY"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ ISSUE_BODY: ${{ steps.build-comment.outputs.updated-text }}
+
+ - name: Create comment - watching for progress
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body-file "exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Enable next step workflow
+ run: |
+ gh workflow enable "Step 1"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/0-welcome.yml b/.github/workflows/0-welcome.yml
deleted file mode 100644
index 513691e..0000000
--- a/.github/workflows/0-welcome.yml
+++ /dev/null
@@ -1,63 +0,0 @@
-name: Step 0, Welcome
-
-# This step triggers after the learner creates a new repository from the template.
-# This workflow updates from step 0 to step 1.
-
-# This will run every time we create push a commit to `main`.
-# Reference: https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows
-on:
- push:
- branches:
- - main
- workflow_dispatch:
-
-# Reference: https://docs.github.com/en/actions/security-guides/automatic-token-authentication
-permissions:
- # Need `contents: read` to checkout the repository.
- # Need `contents: write` to update the step metadata.
- contents: write
-
-jobs:
- # Get the current step to only run the main job when the learner is on the same step.
- get_current_step:
- name: Check current step number
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - id: get_step
- run: |
- echo "current_step=$(cat ./.github/steps/-step.txt)" >> $GITHUB_OUTPUT
- outputs:
- current_step: ${{ steps.get_step.outputs.current_step }}
-
- on_start:
- name: On start
- needs: get_current_step
-
- # We will only run this action when:
- # 1. This repository isn't the template repository.
- # 2. The step is currently 0.
- # Reference: https://docs.github.com/en/actions/learn-github-actions/contexts
- # Reference: https://docs.github.com/en/actions/learn-github-actions/expressions
- if: >-
- ${{ !github.event.repository.is_template
- && needs.get_current_step.outputs.current_step == 0}}
-
- # We'll run Ubuntu for performance instead of Mac or Windows.
- runs-on: ubuntu-latest
-
- steps:
- # We'll need to check out the repository so that we can edit the README.
- - name: Checkout
- uses: actions/checkout@v4
- with:
- fetch-depth: 0 # Let's get all the branches.
-
- # In README.md, switch step 0 for step 1.
- - name: Update to step 1
- uses: skills/action-update-step@v2
- with:
- token: ${{ secrets.GITHUB_TOKEN }}
- from_step: 0
- to_step: 1
diff --git a/.github/workflows/1-first-codespace.yml b/.github/workflows/1-first-codespace.yml
index 543b230..46645ca 100644
--- a/.github/workflows/1-first-codespace.yml
+++ b/.github/workflows/1-first-codespace.yml
@@ -1,70 +1,164 @@
-name: Step 1, Create codespace and push code
+name: Step 1
-# This step triggers after push to main.
-# This workflow updates from step 1 to step 2.
-
-# This will run every time we push to main.
-# Reference: https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows
on:
- workflow_dispatch:
push:
branches:
- main
-# Reference: https://docs.github.com/en/actions/security-guides/automatic-token-authentication
permissions:
- # Need `contents: read` to checkout the repository.
- # Need `contents: write` to update the step metadata.
- contents: write
+ contents: read
+ actions: write
+ issues: write
+
+env:
+ STEP_2_FILE: ".github/steps/2-custom-image.md"
jobs:
- # Get the current step to only run the main job when the learner is on the same step.
- get_current_step:
- name: Check current step number
+ check_commits_count:
+ name: Check commits count
runs-on: ubuntu-latest
+ if: |
+ github.event_name == 'push' &&
+ github.ref == 'refs/heads/main'
+
+ outputs:
+ total_commits: ${{ steps.get_commit_counts.outputs.total_commits }}
+
steps:
- name: Checkout
uses: actions/checkout@v4
- - id: get_step
+ with:
+ fetch-depth: 0 # Fetch all history for all branches and tags
+
+ - name: Get commit count
+ id: get_commit_counts
run: |
- echo "current_step=$(cat ./.github/steps/-step.txt)" >> $GITHUB_OUTPUT
- outputs:
- current_step: ${{ steps.get_step.outputs.current_step }}
-
- on_add_dependency:
- name: On Add dependency
- needs: get_current_step
-
- # We will only run this action when:
- # 1. This repository isn't the template repository.
- # 2. The step is currently 1.
- # Reference: https://docs.github.com/en/actions/learn-github-actions/contexts
- # Reference: https://docs.github.com/en/actions/learn-github-actions/expressions
- if: >-
- ${{ !github.event.repository.is_template
- && needs.get_current_step.outputs.current_step == 1 }}
-
- # We'll run Ubuntu for performance instead of Mac or Windows.
+ total_commits=$(git rev-list --all --count)
+ echo "Total commits in the repository: $total_commits"
+ echo "total_commits=$total_commits" >> $GITHUB_OUTPUT
+
+ find_exercise:
+ needs: [check_commits_count]
+ if: needs.check_commits_count.outputs.total_commits > 1
+ name: Find Exercise Issue
+ uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.5.0
+
+ check_step_work:
+ name: Check step work
runs-on: ubuntu-latest
+ needs: [find_exercise]
+ env:
+ ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }}
steps:
- # We'll need to check out the repository so that we can edit the README.
- name: Checkout
uses: actions/checkout@v4
+
+ - name: Get response templates
+ uses: actions/checkout@v4
+ with:
+ repository: skills/exercise-toolkit
+ path: exercise-toolkit
+ ref: v0.5.0
+
+ - name: Update comment - checking work
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body-file exercise-toolkit/markdown-templates/step-feedback/checking-work.md \
+ --edit-last
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ # START: Check practical exercise
+
+ - name: Check for hello message
+ id: check-hello-message
+ continue-on-error: true
+ uses: skills/action-keyphrase-checker@v1
+ with:
+ text-file: src/hello.py
+ keyphrase: "Hello World"
+ case-sensitive: false
+ minimum-occurrences: 1
+
+ - name: Build message - step results
+ id: build-message-step-results
+ uses: skills/action-text-variables@v2
with:
- fetch-depth: 0 # Let's get all the branches.
+ template-file: exercise-toolkit/markdown-templates/step-feedback/step-results-table.md
+ template-vars: |
+ step_number: 1
+ passed: ${{ !contains(steps.*.outcome, 'failure') }}
+ results_table:
+ - description: "Hello message fixed in hello.py"
+ passed: ${{ steps.check-hello-message.outcome == 'success' }}
- # Verify the learner added the file contents
- - name: Check workflow contents, jobs
- uses: skills/action-check-file@v1
+ - name: Create comment - step results
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body "$COMMENT_BODY" \
+ --edit-last
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ COMMENT_BODY: ${{ steps.build-message-step-results.outputs.updated-text }}
+
+ - name: Fail job if not all checks passed
+ if: contains(steps.*.outcome, 'failure')
+ run: exit 1
+
+ # END: Check practical exercise
+
+ - name: Build message - step finished
+ id: build-message-step-finish
+ uses: skills/action-text-variables@v2
with:
- file: "index.html"
- search: "Hello from the codespace"
+ template-file: exercise-toolkit/markdown-templates/step-feedback/step-finished-prepare-next-step.md
+ template-vars: |
+ next_step_number: 2
+
+ - name: Update comment - step finished
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body "$ISSUE_BODY"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ ISSUE_BODY: ${{ steps.build-message-step-finish.outputs.updated-text }}
+
+ post_next_step_content:
+ name: Post next step content
+ needs: [find_exercise, check_step_work]
+ runs-on: ubuntu-latest
+ env:
+ ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }}
- # In README.md, switch step 1 for step 2.
- - name: Update to step 2
- uses: skills/action-update-step@v2
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Get response templates
+ uses: actions/checkout@v4
with:
- token: ${{ secrets.GITHUB_TOKEN }}
- from_step: 1
- to_step: 2
+ repository: skills/exercise-toolkit
+ path: exercise-toolkit
+ ref: v0.5.0
+
+ - name: Create comment - add step content
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body-file "$STEP_2_FILE"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Create comment - watching for progress
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body-file exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Disable current workflow and enable next one
+ run: |
+ gh workflow disable "Step 1"
+ gh workflow enable "Step 2"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/2-custom-image.yml b/.github/workflows/2-custom-image.yml
index aafd854..3c45cbf 100644
--- a/.github/workflows/2-custom-image.yml
+++ b/.github/workflows/2-custom-image.yml
@@ -1,70 +1,141 @@
-name: Step 2, Custom image check
+name: Step 2
-# This step triggers after First Codespace.
-# This workflow updates from step 2 to step 3.
-
-# This will run every time we push to main.
-# Reference: https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows
on:
- workflow_dispatch:
push:
branches:
- main
+ paths:
+ - ".devcontainer/devcontainer.json"
-# Reference: https://docs.github.com/en/actions/security-guides/automatic-token-authentication
permissions:
- # Need `contents: read` to checkout the repository.
- # Need `contents: write` to update the step metadata.
- contents: write
+ contents: read
+ actions: write
+ issues: write
+
+env:
+ STEP_3_FILE: ".github/steps/3-customize-codespace.md"
jobs:
- # Get the current step to only run the main job when the learner is on the same step.
- get_current_step:
- name: Check current step number
+ find_exercise:
+ name: Find Exercise Issue
+ uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.5.0
+
+ check_step_work:
+ name: Check step work
runs-on: ubuntu-latest
+ needs: [find_exercise]
+ env:
+ ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }}
+
steps:
- name: Checkout
uses: actions/checkout@v4
- - id: get_step
+
+ - name: Get response templates
+ uses: actions/checkout@v4
+ with:
+ repository: skills/exercise-toolkit
+ path: exercise-toolkit
+ ref: v0.5.0
+
+ - name: Update comment - checking work
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body-file exercise-toolkit/markdown-templates/step-feedback/checking-work.md \
+ --edit-last
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ # START: Check practical exercise
+
+ - name: Check container image
+ id: check-container-image
+ continue-on-error: true
+ uses: skills/action-keyphrase-checker@v1
+ with:
+ text-file: .devcontainer/devcontainer.json
+ keyphrase: "devcontainers/universal:latest"
+ case-sensitive: false
+ minimum-occurrences: 1
+
+ - name: Build message - step results
+ id: build-message-step-results
+ uses: skills/action-text-variables@v2
+ with:
+ template-file: exercise-toolkit/markdown-templates/step-feedback/step-results-table.md
+ template-vars: |
+ step_number: 2
+ passed: ${{ !contains(steps.*.outcome, 'failure') }}
+ results_table:
+ - description: "Devcontainer image set to universal:latest"
+ passed: ${{ steps.check-container-image.outcome == 'success' }}
+
+ - name: Create comment - step results
run: |
- echo "current_step=$(cat ./.github/steps/-step.txt)" >> $GITHUB_OUTPUT
- outputs:
- current_step: ${{ steps.get_step.outputs.current_step }}
-
- on_DependabotPrCreated:
- name: On Creation of a PR
- needs: get_current_step
-
- # We will only run this action when:
- # 1. This repository isn't the template repository.
- # 2. The step is currently 2.
- # Reference: https://docs.github.com/en/actions/learn-github-actions/contexts
- # Reference: https://docs.github.com/en/actions/learn-github-actions/expressions
- if: >-
- ${{ !github.event.repository.is_template
- && needs.get_current_step.outputs.current_step == 2 }}
-
- # We'll run Ubuntu for performance instead of Mac or Windows.
+ gh issue comment "$ISSUE_URL" \
+ --body "$COMMENT_BODY" \
+ --edit-last
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ COMMENT_BODY: ${{ steps.build-message-step-results.outputs.updated-text }}
+
+ - name: Fail job if not all checks passed
+ if: contains(steps.*.outcome, 'failure')
+ run: exit 1
+
+ # END: Check practical exercise
+
+ - name: Build message - step finished
+ id: build-message-step-finish
+ uses: skills/action-text-variables@v2
+ with:
+ template-file: exercise-toolkit/markdown-templates/step-feedback/step-finished-prepare-next-step.md
+ template-vars: |
+ next_step_number: 3
+
+ - name: Update comment - step finished
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body "$ISSUE_BODY"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ ISSUE_BODY: ${{ steps.build-message-step-finish.outputs.updated-text }}
+
+ post_next_step_content:
+ name: Post next step content
+ needs: [find_exercise, check_step_work]
runs-on: ubuntu-latest
+ env:
+ ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }}
steps:
- # We'll need to check out the repository so that we can edit the README.
- name: Checkout
uses: actions/checkout@v4
- with:
- fetch-depth: 0 # Let's get all the branches.
- # Verify the devcontainer.json has an image.
- - name: Check devcontainer.json
- uses: skills/action-check-file@v1
+ - name: Get response templates
+ uses: actions/checkout@v4
with:
- file: ".devcontainer/devcontainer.json"
- search: "mcr\\.microsoft\\.com/vscode/devcontainers/universal:latest"
+ repository: skills/exercise-toolkit
+ path: exercise-toolkit
+ ref: v0.5.0
- # In README.md, switch step 2 for step 3.
- - name: Update to step 3
- uses: skills/action-update-step@v2
- with:
- token: ${{ secrets.GITHUB_TOKEN }}
- from_step: 2
- to_step: 3
+ - name: Create comment - add step content
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body-file "$STEP_3_FILE"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Create comment - watching for progress
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body-file exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Disable current workflow and enable next one
+ run: |
+ gh workflow disable "Step 2"
+ gh workflow enable "Step 3"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/3-customize-codespace.yml b/.github/workflows/3-customize-codespace.yml
index b1ba71c..3302b60 100644
--- a/.github/workflows/3-customize-codespace.yml
+++ b/.github/workflows/3-customize-codespace.yml
@@ -1,70 +1,177 @@
-name: Step 3, Customize Codespace
+name: Step 3
-# This step triggers after we push to main.
-# This workflow updates from step 3 to step 4.
-
-# This will run every time.
-# Reference: https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows
on:
- workflow_dispatch:
push:
branches:
- main
+ paths:
+ - ".devcontainer/**"
-# Reference: https://docs.github.com/en/actions/security-guides/automatic-token-authentication
permissions:
- # Need `contents: read` to checkout the repository.
- # Need `contents: write` to update the step metadata.
- contents: write
+ contents: read
+ actions: write
+ issues: write
+
+env:
+ STEP_4_FILE: ".github/steps/4-use-codespace.md"
jobs:
- # Get the current step to only run the main job when the learner is on the same step.
- get_current_step:
- name: Check current step number
+ find_exercise:
+ name: Find Exercise Issue
+ uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.5.0
+
+ check_step_work:
+ name: Check step work
runs-on: ubuntu-latest
+ needs: [find_exercise]
+ env:
+ ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }}
+
steps:
- name: Checkout
uses: actions/checkout@v4
- - id: get_step
+
+ - name: Get response templates
+ uses: actions/checkout@v4
+ with:
+ repository: skills/exercise-toolkit
+ path: exercise-toolkit
+ ref: v0.5.0
+
+ - name: Update comment - checking work
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body-file exercise-toolkit/markdown-templates/step-feedback/checking-work.md \
+ --edit-last
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ # START: Check practical exercise
+
+ - name: Check features set
+ id: check-features-set
+ continue-on-error: true
+ uses: skills/action-keyphrase-checker@v1
+ with:
+ text-file: .devcontainer/devcontainer.json
+ keyphrase: "features"
+ case-sensitive: false
+ minimum-occurrences: 1
+
+ - name: Check customizations set
+ id: check-customizations-set
+ continue-on-error: true
+ uses: skills/action-keyphrase-checker@v1
+ with:
+ text-file: .devcontainer/devcontainer.json
+ keyphrase: "customizations"
+ case-sensitive: false
+ minimum-occurrences: 1
+
+ - name: Check command set
+ id: check-command-set
+ continue-on-error: true
+ uses: skills/action-keyphrase-checker@v1
+ with:
+ text-file: .devcontainer/devcontainer.json
+ keyphrase: "postCreateCommand"
+ case-sensitive: false
+ minimum-occurrences: 1
+
+ - name: Check postCreate script
+ id: check-postcreate-script
+ continue-on-error: true
+ uses: skills/action-keyphrase-checker@v1
+ with:
+ text-file: .devcontainer/postCreate.sh
+ keyphrase: "install sl"
+ case-sensitive: false
+ minimum-occurrences: 1
+
+ - name: Build message - step results
+ id: build-message-step-results
+ uses: skills/action-text-variables@v2
+ with:
+ template-file: exercise-toolkit/markdown-templates/step-feedback/step-results-table.md
+ template-vars: |
+ step_number: 3
+ passed: ${{ !contains(steps.*.outcome, 'failure') }}
+ results_table:
+ - description: "Features added to devcontainer.json"
+ passed: ${{ steps.check-features-set.outcome == 'success' }}
+ - description: "Customizations added to devcontainer.json"
+ passed: ${{ steps.check-customizations-set.outcome == 'success' }}
+ - description: "Postcreate command added to devcontainer.json"
+ passed: ${{ steps.check-command-set.outcome == 'success' }}
+ - description: "Postcreate script created"
+ passed: ${{ steps.check-postcreate-script.outcome == 'success' }}
+
+ - name: Create comment - step results
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body "$COMMENT_BODY" \
+ --edit-last
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ COMMENT_BODY: ${{ steps.build-message-step-results.outputs.updated-text }}
+
+ - name: Fail job if not all checks passed
+ if: contains(steps.*.outcome, 'failure')
+ run: exit 1
+
+ # END: Check practical exercise
+
+ - name: Build message - step finished
+ id: build-message-step-finish
+ uses: skills/action-text-variables@v2
+ with:
+ template-file: exercise-toolkit/markdown-templates/step-feedback/step-finished-prepare-next-step.md
+ template-vars: |
+ next_step_number: 4
+
+ - name: Update comment - step finished
run: |
- echo "current_step=$(cat ./.github/steps/-step.txt)" >> $GITHUB_OUTPUT
- outputs:
- current_step: ${{ steps.get_step.outputs.current_step }}
-
- on_DependabotSecurityUpdates:
- name: On Dependabot Security Updates
- needs: get_current_step
-
- # We will only run this action when:
- # 1. This repository isn't the template repository.
- # 2. The step is currently 3.
- # Reference: https://docs.github.com/en/actions/learn-github-actions/contexts
- # Reference: https://docs.github.com/en/actions/learn-github-actions/expressions
- if: >-
- ${{ !github.event.repository.is_template
- && needs.get_current_step.outputs.current_step == 3 }}
-
- # We'll run Ubuntu for performance instead of Mac or Windows.
+ gh issue comment "$ISSUE_URL" \
+ --body "$ISSUE_BODY"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ ISSUE_BODY: ${{ steps.build-message-step-finish.outputs.updated-text }}
+
+ post_next_step_content:
+ name: Post next step content
+ needs: [find_exercise, check_step_work]
runs-on: ubuntu-latest
+ env:
+ ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }}
steps:
- # We'll need to check out the repository so that we can edit the README.
- name: Checkout
uses: actions/checkout@v4
- with:
- fetch-depth: 0 # Let's get all the branches.
- # Verify the postCreateCommand was added.
- - name: Check for postCreateCommand
- uses: skills/action-check-file@v1
+ - name: Get response templates
+ uses: actions/checkout@v4
with:
- file: ".devcontainer/devcontainer.json"
- search: "postCreateCommand"
+ repository: skills/exercise-toolkit
+ path: exercise-toolkit
+ ref: v0.5.0
- # In README.md, switch step 3 for step 4.
- - name: Update to step 4
- uses: skills/action-update-step@v2
- with:
- token: ${{ secrets.GITHUB_TOKEN }}
- from_step: 3
- to_step: 4
+ - name: Create comment - add step content
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body-file "$STEP_4_FILE"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Create comment - watching for progress
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body-file exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Disable current workflow and enable next one
+ run: |
+ gh workflow disable "Step 3"
+ gh workflow enable "Step 4"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/4-personalize-codespace.yml b/.github/workflows/4-personalize-codespace.yml
deleted file mode 100644
index 928fe98..0000000
--- a/.github/workflows/4-personalize-codespace.yml
+++ /dev/null
@@ -1,72 +0,0 @@
-name: Step 4, Personalize your Codespace
-
-# This step triggers after push to main#setup.sh.
-# This workflow updates from step 4 to step X.
-
-# This will run every time we push to main#setup.sh.
-# Reference: https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows
-on:
- workflow_dispatch:
- push:
- branches:
- - main
- paths:
- - "setup.sh"
-
-# Reference: https://docs.github.com/en/actions/security-guides/automatic-token-authentication
-permissions:
- # Need `contents: read` to checkout the repository.
- # Need `contents: write` to update the step metadata.
- contents: write
-
-jobs:
- # Get the current step to only run the main job when the learner is on the same step.
- get_current_step:
- name: Check current step number
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - id: get_step
- run: |
- echo "current_step=$(cat ./.github/steps/-step.txt)" >> $GITHUB_OUTPUT
- outputs:
- current_step: ${{ steps.get_step.outputs.current_step }}
-
- on_update_setup:
- name: On update setup
- needs: get_current_step
-
- # We will only run this action when:
- # 1. This repository isn't the template repository.
- # 2. The step is currently 4.
- # Reference: https://docs.github.com/en/actions/learn-github-actions/contexts
- # Reference: https://docs.github.com/en/actions/learn-github-actions/expressions
- if: >-
- ${{ !github.event.repository.is_template
- && needs.get_current_step.outputs.current_step == 4}}
-
- # We'll run Ubuntu for performance instead of Mac or Windows.
- runs-on: ubuntu-latest
-
- steps:
- # We'll need to check out the repository so that we can edit the README.
- - name: Checkout
- uses: actions/checkout@v4
- with:
- fetch-depth: 0 # Let's get all the branches.
-
- # Verify the setup.sh added the file contents.
- - name: Check workflow contents, jobs
- uses: skills/action-check-file@v1
- with:
- file: "setup.sh"
- search: "install sl"
-
- # In README.md, switch step 4 for step X.
- - name: Update to step X
- uses: skills/action-update-step@v2
- with:
- token: ${{ secrets.GITHUB_TOKEN }}
- from_step: 4
- to_step: X
diff --git a/.github/workflows/4-use-codespace.yml b/.github/workflows/4-use-codespace.yml
new file mode 100644
index 0000000..888acc2
--- /dev/null
+++ b/.github/workflows/4-use-codespace.yml
@@ -0,0 +1,77 @@
+name: Step 4
+
+on:
+ issue_comment:
+ types: [created]
+
+permissions:
+ contents: write
+ actions: write
+ issues: write
+
+env:
+ REVIEW_FILE: ".github/steps/x-review.md"
+
+jobs:
+ required_issue_comment_keywords:
+ name: Check issue comment text for required keyword
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check for professortocat reference
+ uses: skills/action-keyphrase-checker@v1
+ with:
+ text: ${{ github.event.comment.body }}
+ keyphrase: 'professortocat'
+ case-sensitive: false
+ minimum-occurrences: 1
+ - name: Check for codespace reference
+ uses: skills/action-keyphrase-checker@v1
+ with:
+ text: ${{ github.event.comment.body }}
+ keyphrase: 'codespace'
+ case-sensitive: false
+ minimum-occurrences: 1
+
+ find_exercise:
+ needs: [required_issue_comment_keywords]
+ name: Find Exercise Issue
+ uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.5.0
+
+ post_review_content:
+ name: Post review content
+ needs: [find_exercise]
+ runs-on: ubuntu-latest
+ env:
+ ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }}
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Create comment - add step content
+ run: |
+ gh issue comment "$ISSUE_URL" \
+ --body-file "$REVIEW_FILE"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ finish_exercise:
+ name: Finish Exercise
+ needs: [find_exercise, post_review_content]
+ uses: skills/exercise-toolkit/.github/workflows/finish-exercise.yml@v0.5.0
+ with:
+ issue-url: ${{ needs.find_exercise.outputs.issue-url }}
+
+ disable_workflow:
+ name: Disable this workflow
+ needs: [find_exercise, post_review_content]
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Disable current workflow
+ run: gh workflow disable "${{github.workflow}}"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..0f5b528
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,11 @@
+{
+ "configurations": [
+ {
+ "name": "Launch Python",
+ "type": "debugpy",
+ "request": "launch",
+ "program": "src/hello.py",
+ "console": "integratedTerminal"
+ }
+ ]
+}
diff --git a/README.md b/README.md
index 5e34903..74a550b 100644
--- a/README.md
+++ b/README.md
@@ -1,76 +1,47 @@
-