diff --git a/.github/workflows/0-start-exercise.yml b/.github/workflows/0-start-exercise.yml index edf4a87..1c95c66 100644 --- a/.github/workflows/0-start-exercise.yml +++ b/.github/workflows/0-start-exercise.yml @@ -18,7 +18,7 @@ jobs: if: | !github.event.repository.is_template name: Start Exercise - uses: skills/exercise-toolkit/.github/workflows/start-exercise.yml@v0.3.0 + uses: skills/exercise-toolkit/.github/workflows/start-exercise.yml@v0.4.0 with: exercise-title: "Getting Started with GitHub Copilot" intro-message: "Welcome to the exciting world of GitHub Copilot! 🚀 In this exercise, you'll unlock the potential of this AI-powered coding assistant to accelerate your development process. Let's dive in and have some fun exploring the future of coding together! 💻✨" @@ -38,22 +38,18 @@ jobs: - name: Get response templates uses: actions/checkout@v4 with: - repository: skills/response-templates - path: skills-response-templates - - - name: Configure Git user - run: | - git config user.name github-actions[bot] - git config user.email github-actions[bot]@users.noreply.github.com + repository: skills/exercise-toolkit + path: exercise-toolkit + ref: v0.4.0 - name: Build comment - add step content id: build-comment - uses: skills/action-text-variables@v1 + uses: skills/action-text-variables@v2 with: template-file: ${{ env.STEP_1_FILE }} template-vars: | - login=${{ github.actor }} - full_repo_name=${{ github.repository }} + login: ${{ github.actor }} + full_repo_name: ${{ github.repository }} - name: Create comment - add step content run: | @@ -66,13 +62,12 @@ jobs: - name: Create comment - watching for progress run: | gh issue comment "$ISSUE_URL" \ - --body-file "skills-response-templates/step-feedback/watching-for-progress.md" + --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 enable "Step 0" # Already disabled gh workflow enable "Step 1" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/1-preparing.yml b/.github/workflows/1-preparing.yml index dc3c6c5..621f0e5 100644 --- a/.github/workflows/1-preparing.yml +++ b/.github/workflows/1-preparing.yml @@ -16,7 +16,7 @@ env: jobs: find_exercise: name: Find Exercise Issue - uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.1.0 + uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.4.0 check_step_work: name: Check step work @@ -32,13 +32,14 @@ jobs: - name: Get response templates uses: actions/checkout@v4 with: - repository: skills/response-templates - path: skills-response-templates + repository: skills/exercise-toolkit + path: exercise-toolkit + ref: v0.4.0 - name: Update comment - checking work run: | gh issue comment "$ISSUE_URL" \ - --body-file skills-response-templates/step-feedback/checking-work.md \ + --body-file exercise-toolkit/markdown-templates/step-feedback/checking-work.md \ --edit-last env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -52,11 +53,11 @@ jobs: - name: Build message - step finished id: build-message-step-finish - uses: skills/action-text-variables@v1 + uses: skills/action-text-variables@v2 with: - template-file: skills-response-templates/step-feedback/step-finished-prepare-next-step.md + template-file: exercise-toolkit/markdown-templates/step-feedback/step-finished-prepare-next-step.md template-vars: | - next_step_number=2 + next_step_number: 2 - name: Update comment - step finished run: | @@ -81,8 +82,9 @@ jobs: - name: Get response templates uses: actions/checkout@v4 with: - repository: skills/response-templates - path: skills-response-templates + repository: skills/exercise-toolkit + path: exercise-toolkit + ref: v0.4.0 - name: Create comment - add step content run: | @@ -94,7 +96,7 @@ jobs: - name: Create comment - watching for progress run: | gh issue comment "$ISSUE_URL" \ - --body-file skills-response-templates/step-feedback/watching-for-progress.md + --body-file exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/2-first-introduction.yml b/.github/workflows/2-first-introduction.yml index 100e158..2ad7adc 100644 --- a/.github/workflows/2-first-introduction.yml +++ b/.github/workflows/2-first-introduction.yml @@ -18,7 +18,7 @@ env: jobs: find_exercise: name: Find Exercise Issue - uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.1.0 + uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.4.0 check_step_work: name: Check step work @@ -34,74 +34,67 @@ jobs: - name: Get response templates uses: actions/checkout@v4 with: - repository: skills/response-templates - path: skills-response-templates + repository: skills/exercise-toolkit + path: exercise-toolkit + ref: v0.4.0 - name: Update comment - checking work run: | gh issue comment "$ISSUE_URL" \ - --body-file skills-response-templates/step-feedback/checking-work.md \ + --body-file exercise-toolkit/markdown-templates/step-feedback/checking-work.md \ --edit-last env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # START: Check practical exercise - # Search for the comment about registration validation - - name: Check contents of 'src/app.py' - run: | - # File and expected phrase - file="src/app.py" - keyphrase="Validate student is not already signed up" - - # Fail the workflow if the file content is missing - if ! grep -q "$keyphrase" "$file"; then - message="It seems our registration validation bug has not been fixed. Please try again." - gh issue comment "$ISSUE_URL" \ - --body "$message" \ - --edit-last - exit 1 - fi - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - # Check the number of activities in the file by counting the json keys - name: Check for additional student activities + id: check-additional-activities + continue-on-error: true + uses: skills/action-keyphrase-checker@v1 + with: + text-file: src/app.py + keyphrase: '"description"' + minimum-occurrences: 4 + case-sensitive: false + + - 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: "New activities added to src/app.py. We found ${{ steps.check-additional-activities.outputs.occurrences }} activities (minimum 4 required)" + passed: ${{ steps.check-additional-activities.outcome == 'success' }} + + - name: Create comment - step results run: | - # File and phrase to count - file="src/app.py" - keyphrase='"description":' - minimum_occurences=4 - - # Get the number of occurences of the keyphrase - found_occurences=$(grep -o "$keyphrase" "$file" | wc -l) - - # If the number of occurences is less than the minimum, fail the workflow and send a message - if [ "$found_occurences" -lt "$minimum_occurences" ]; then - message="No new student activities were found. Please use Copilot to generate some and try again." - gh issue comment "$ISSUE_URL" \ - --body "$message" \ - --edit-last - exit 1 - fi + 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 }} - # END: Check practical exercise + - name: Fail job if not all checks passed + if: contains(steps.*.outcome, 'failure') + run: exit 1 - name: Build message - step finished id: build-message-step-finish - uses: skills/action-text-variables@v1 + uses: skills/action-text-variables@v2 with: - template-file: skills-response-templates/step-feedback/step-finished-prepare-next-step.md + template-file: exercise-toolkit/markdown-templates/step-feedback/step-finished-prepare-next-step.md template-vars: | - next_step_number=3 + next_step_number: 3 - name: Update comment - step finished run: | gh issue comment "$ISSUE_URL" \ - --body "$ISSUE_BODY" \ - --edit-last + --body "$ISSUE_BODY" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} ISSUE_BODY: ${{ steps.build-message-step-finish.outputs.updated-text }} @@ -120,8 +113,9 @@ jobs: - name: Get response templates uses: actions/checkout@v4 with: - repository: skills/response-templates - path: skills-response-templates + repository: skills/exercise-toolkit + path: exercise-toolkit + ref: v0.4.0 - name: Create comment - add step content run: | @@ -133,7 +127,7 @@ jobs: - name: Create comment - watching for progress run: | gh issue comment "$ISSUE_URL" \ - --body-file skills-response-templates/step-feedback/watching-for-progress.md + --body-file exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/3-copilot-edits.yml b/.github/workflows/3-copilot-edits.yml index 49efc34..251c9d0 100644 --- a/.github/workflows/3-copilot-edits.yml +++ b/.github/workflows/3-copilot-edits.yml @@ -18,7 +18,7 @@ env: jobs: find_exercise: name: Find Exercise Issue - uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.1.0 + uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.4.0 check_step_work: name: Check step work @@ -34,86 +34,50 @@ jobs: - name: Get response templates uses: actions/checkout@v4 with: - repository: skills/response-templates - path: skills-response-templates + repository: skills/exercise-toolkit + path: exercise-toolkit + ref: v0.4.0 - name: Update comment - checking work run: | gh issue comment "$ISSUE_URL" \ - --body-file skills-response-templates/step-feedback/checking-work.md \ + --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 participant info on activity cards - id: check-user-work - run: | - # Checks to perform - checks='{ - "app_js": { - "name": "app.js", - "passed": true, - "message": "" - }, - "styles_css": { - "name": "styles.css", - "passed": true, - "message": "" - } - }' - - # Check for participants info in app.js - file="src/static/app.js" - keyphrase='participant' - minimum_occurences=3 - found_occurences=$(grep -o "$keyphrase" "$file" | wc -l) - if [ "$found_occurences" -lt "$minimum_occurences" ]; then - checks=$(echo $checks | jq '.app_js.passed = false') - checks=$(echo $checks | jq '.app_js.message = "Please use Copilot to update the web application activity cards to show participant info."') - fi - - # Check for participants info in styles.css - file="src/static/styles.css" - keyphrase='participant' - minimum_occurences=1 - found_occurences=$(grep -o "$keyphrase" "$file" | wc -l) - if [ "$found_occurences" -lt "$minimum_occurences" ]; then - checks=$(echo $checks | jq '.styles_css.passed = false') - checks=$(echo $checks | jq '.styles_css.message = "Please use Copilot to update the web application styling to support participant info."') - fi - - # Verify all checks passed - passed=$(echo $checks | jq '. | all(.passed?)') - - # Flatten to an array for returning. Allows iteration during rendering. - results=$(echo $checks | jq 'to_entries | map({name: .key} + .value)') - - # Save pass status to output - echo "passed=$passed" >> $GITHUB_OUTPUT - - # Save results to output - echo 'results<> $GITHUB_OUTPUT - echo $results >> $GITHUB_OUTPUT - echo 'EOF' >> $GITHUB_OUTPUT - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Check for participant info in app.js + id: check-app-js + continue-on-error: true + uses: skills/action-keyphrase-checker@v1 + with: + text-file: src/static/app.js + keyphrase: participant + minimum-occurrences: 3 + case-sensitive: false + + - name: Check for participant info in styles.css + id: check-styles + continue-on-error: true + uses: skills/action-keyphrase-checker@v1 + with: + text-file: src/static/styles.css + keyphrase: participant + case-sensitive: false - name: Build message - step results id: build-message-step-results - uses: skills/action-text-variables@v1 + uses: skills/action-text-variables@v2 with: - template-file: skills-response-templates/step-feedback/step-results.md - template-vars: '{ - "step_number": 3, - "passed": ${{ steps.check-user-work.outputs.passed }}, - "results_table": ${{ steps.check-user-work.outputs.results }}, - "tips": [ - "Copilot is becoming more capable everyday. Make sure to always be experimenting!", - "Try testing what Copilot can do. Something like: Add a dark mode toggle in the top right." - ] - }' + 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: "Check app.js for participant info" + passed: ${{ steps.check-app-js.outcome == 'success' }} + - description: "Participant styling updated in styles.css" + passed: ${{ steps.check-styles.outcome == 'success' }} - name: Create comment - step results run: | @@ -125,18 +89,16 @@ jobs: COMMENT_BODY: ${{ steps.build-message-step-results.outputs.updated-text }} - name: Fail job if not all checks passed - if: steps.check-user-work.outputs.passed == 'false' + 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@v1 + uses: skills/action-text-variables@v2 with: - template-file: skills-response-templates/step-feedback/step-finished-prepare-next-step.md + template-file: exercise-toolkit/markdown-templates/step-feedback/step-finished-prepare-next-step.md template-vars: | - next_step_number=4 + next_step_number: 4 - name: Update comment - step finished run: | @@ -160,8 +122,9 @@ jobs: - name: Get response templates uses: actions/checkout@v4 with: - repository: skills/response-templates - path: skills-response-templates + repository: skills/exercise-toolkit + path: exercise-toolkit + ref: v0.4.0 - name: Create comment - add step content run: | @@ -173,7 +136,7 @@ jobs: - name: Create comment - watching for progress run: | gh issue comment "$ISSUE_URL" \ - --body-file skills-response-templates/step-feedback/watching-for-progress.md + --body-file exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/3b-copilot-agent-mode.yml b/.github/workflows/3b-copilot-agent-mode.yml index ef63460..cd362b6 100644 --- a/.github/workflows/3b-copilot-agent-mode.yml +++ b/.github/workflows/3b-copilot-agent-mode.yml @@ -36,7 +36,7 @@ jobs: find_exercise: name: Find Exercise Issue - uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.1.0 + uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.4.0 post_step_3b_content: name: Post step 3b content diff --git a/.github/workflows/4-copilot-on-github.yml b/.github/workflows/4-copilot-on-github.yml index 9bda17a..6c16240 100644 --- a/.github/workflows/4-copilot-on-github.yml +++ b/.github/workflows/4-copilot-on-github.yml @@ -18,7 +18,7 @@ env: jobs: find_exercise: name: Find Exercise Issue - uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.1.0 + uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.4.0 check_step_work: name: Check step work @@ -31,11 +31,13 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Get response templates uses: actions/checkout@v4 with: - repository: skills/response-templates - path: skills-response-templates + repository: skills/exercise-toolkit + path: exercise-toolkit + ref: v0.4.0 # START: Check practical exercise @@ -46,7 +48,7 @@ jobs: - name: Create comment - step finished - final review next run: | gh issue comment "$ISSUE_URL" \ - --body-file skills-response-templates/step-feedback/lesson-review.md + --body-file exercise-toolkit/markdown-templates/step-feedback/lesson-review.md env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -61,11 +63,13 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Get response templates uses: actions/checkout@v4 with: - repository: skills/response-templates - path: skills-response-templates + repository: skills/exercise-toolkit + path: exercise-toolkit + ref: v0.4.0 - name: Create comment - add step content run: | @@ -77,7 +81,7 @@ jobs: finish_exercise: name: Finish Exercise needs: [find_exercise, post_review_content] - uses: skills/exercise-toolkit/.github/workflows/finish-exercise.yml@v0.3.0 + uses: skills/exercise-toolkit/.github/workflows/finish-exercise.yml@v0.4.0 with: issue-url: ${{ needs.find_exercise.outputs.issue-url }} diff --git a/.github/workflows/4b-copilot-on-github.yml b/.github/workflows/4b-copilot-on-github.yml index 5a083a3..ec4f8d6 100644 --- a/.github/workflows/4b-copilot-on-github.yml +++ b/.github/workflows/4b-copilot-on-github.yml @@ -2,6 +2,7 @@ name: Step 4b # Copilot on GitHub on: # Trigger if PR Description is edited + # Disabled because PR summaries are not available for free accounts # pull_request: # branches: # - main @@ -21,7 +22,7 @@ permissions: jobs: find_exercise: name: Find Exercise Issue - uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.1.0 + uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.4.0 check_step_work: name: Check step work @@ -37,81 +38,64 @@ jobs: - name: Get response templates uses: actions/checkout@v4 with: - repository: skills/response-templates - path: skills-response-templates + repository: skills/exercise-toolkit + path: exercise-toolkit + ref: v0.4.0 # START: Check practical exercise - - name: Check for pr description and copilot review - id: check-user-work + - name: Check for PR description + continue-on-error: true + id: check-pr-description run: | - # Checks to perform - checks='{ - "pr_description": { - "name": "PR Description", - "passed": true, - "message": "" - }, - "copilot_review": { - "name": "Copilot Review", - "passed": true, - "message": "" - } - }' - # Check if PR has a description and minimum length min_length=15 body_length=$(echo "$PR_Body" | wc -c) - echo "PR decription length: $body_length" + echo "PR description length: $body_length" + if [ "$body_length" -lt $min_length ]; then - checks=$(echo $checks | jq '.pr_description.passed = false') - checks=$(echo $checks | jq '.pr_description.message = "Please use Copilot to generate a pull request description."') + echo "::error::PR description is too short or missing" + exit 1 fi + env: + PR_Body: ${{ github.event.pull_request.body }} + - name: Check for Copilot review + id: check-copilot-review + run: | # Check for a PR Review from Copilot reviews=$(gh pr view --repo $REPO $PR_NUMBER --json reviews) authors=$(echo "$reviews" | jq '.reviews[].author.login') + if echo "$authors" | grep -q "copilot-pull-request-reviewer"; then - echo "Copilot has reviewed this PR." - else - echo "Copilot has NOT reviewed this PR." - checks=$(echo $checks | jq '.copilot_review.passed = false') - checks=$(echo $checks | jq '.copilot_review.message = "Please request a review from Copilot."') + echo "Copilot has reviewed this PR." + else + echo "Copilot has NOT reviewed this PR." + echo "::error::No review from Copilot found" + exit 1 fi - - # Verify all checks passed - passed=$(echo $checks | jq '. | all(.passed?)') - - # Flatten to an array for returning. Allows iteration during rendering. - results=$(echo $checks | jq 'to_entries | map({name: .key} + .value)') - - # Save pass status to output - echo "passed=$passed" >> $GITHUB_OUTPUT - - # Save results to output - echo 'results<> $GITHUB_OUTPUT - echo $results >> $GITHUB_OUTPUT - echo 'EOF' >> $GITHUB_OUTPUT env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PR_Body: ${{ github.event.pull_request.body }} REPO: ${{ github.repository }} PR_NUMBER: ${{ github.event.pull_request.number }} + continue-on-error: true - name: Build message - step results id: build-message-step-results - uses: skills/action-text-variables@v1 + uses: skills/action-text-variables@v2 with: - template-file: skills-response-templates/step-feedback/step-results.md - template-vars: '{ - "step_number": 4, - "passed": ${{ steps.check-user-work.outputs.passed }}, - "results_table": ${{ steps.check-user-work.outputs.results }}, - "tips": [ - "Copilot review will also suggest changes for common mistakes and typos.", - "You can use repository rulesets to automatically require a review from Copilot." - ] - }' + template-file: exercise-toolkit/markdown-templates/step-feedback/step-results-table.md + template-vars: | + step_number: 4 + passed: ${{ !contains(steps.*.outcome, 'failure') }} + results_table: + - description: "Pull request contains a descriptive overview" + passed: ${{ steps.check-pr-description.outcome == 'success' }} + - description: "Pull request received a review from GitHub Copilot" + passed: ${{ steps.check-copilot-review.outcome == 'success' }} + tips: + - "If you already requested Copilot review and this check did not pass, go to your repository [actions](https://github.com/${{github.repository}}/actions) tab to check if a workflow run is awaiting your manual approval." + - "You can use repository rulesets to automatically require a review from Copilot." - name: Create comment - step results run: | @@ -122,7 +106,7 @@ jobs: COMMENT_BODY: ${{ steps.build-message-step-results.outputs.updated-text }} - name: Fail job if not all checks passed - if: steps.check-user-work.outputs.passed == 'false' + if: contains(steps.*.outcome, 'failure') run: exit 1 # END: Check practical exercise