mirror of
https://github.com/farcasclaudiu/learn-build-apps-copilot-agent.git
synced 2026-06-22 07:01:37 +03:00
Initial commit
This commit is contained in:
@@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"name": "OctoFit Tracker Multi-tier Application Codespace",
|
||||||
|
"image": "mcr.microsoft.com/devcontainers/base:jammy",
|
||||||
|
"features": {
|
||||||
|
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
|
||||||
|
"ghcr.io/devcontainers/features/github-cli:1": {},
|
||||||
|
"ghcr.io/devcontainers/features/node:1": {
|
||||||
|
"version": "lts",
|
||||||
|
"pnpmVersion": "latest",
|
||||||
|
"nvmVersion": "latest"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"postCreateCommand": "sudo chmod +x ./.devcontainer/post_create.sh && ./.devcontainer/post_create.sh",
|
||||||
|
"postStartCommand": "sudo chmod +x ./.devcontainer/post_start.sh && ./.devcontainer/post_start.sh",
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": [
|
||||||
|
"github.copilot",
|
||||||
|
"markdown-lint.markdownlinter",
|
||||||
|
"ms-vscode.vscode-typescript-next",
|
||||||
|
"dbaeumer.vscode-eslint"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"chat.agent.enabled": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"forwardPorts": [
|
||||||
|
5173,
|
||||||
|
8000,
|
||||||
|
27017
|
||||||
|
],
|
||||||
|
"portsAttributes": {
|
||||||
|
"5173": {
|
||||||
|
"label": "octofit-tracker-frontend",
|
||||||
|
"requireLocalPort": true
|
||||||
|
},
|
||||||
|
"8000": {
|
||||||
|
"label": "octofit-tracker-api",
|
||||||
|
"requireLocalPort": true
|
||||||
|
},
|
||||||
|
"27017": {
|
||||||
|
"label": "octofit-tracker-mongodb",
|
||||||
|
"requireLocalPort": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+11
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This script is run after the container is created.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
wget -qO - https://pgp.mongodb.com/server-6.0.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/mongodb-server-6.0.gpg > /dev/null
|
||||||
|
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y mongodb-org
|
||||||
|
sudo mkdir -p /usr/local/etc/vscode-dev-containers
|
||||||
|
sudo cp --force ./.devcontainer/welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt
|
||||||
Executable
+97
@@ -0,0 +1,97 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This script is run after the container starts up.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
die() {
|
||||||
|
echo "ERROR: $@" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
: "${CODESPACE_NAME:?CODESPACE_NAME environment variable not set. This script should be run in a GitHub Codespace environment.}"
|
||||||
|
|
||||||
|
echo "Setting multi-tier application port visibility..."
|
||||||
|
gh cs ports visibility 8000:public -c "$CODESPACE_NAME" || die "Failed to set 8000 public"
|
||||||
|
gh cs ports visibility 5173:public -c "$CODESPACE_NAME" || die "Failed to set 5173 public"
|
||||||
|
gh cs ports visibility 27017:private -c "$CODESPACE_NAME" || die "Failed to set 27017 private"
|
||||||
|
|
||||||
|
echo "Preparing MongoDB data dir..."
|
||||||
|
sudo mkdir -p /data/db || die "mkdir failed"
|
||||||
|
sudo chmod 777 /data/db || die "chmod failed"
|
||||||
|
|
||||||
|
LOGFILE=/tmp/mongod.log
|
||||||
|
MAX_START_TRIES=3
|
||||||
|
READY_CHECK_RETRIES=15
|
||||||
|
READY_CHECK_INTERVAL=1
|
||||||
|
|
||||||
|
is_running() {
|
||||||
|
ps aux | grep '[m]ongod' >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
mongod_pid() {
|
||||||
|
pgrep -x mongod || true
|
||||||
|
}
|
||||||
|
|
||||||
|
start_mongod() {
|
||||||
|
if is_running; then
|
||||||
|
echo "mongod already running"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
> "$LOGFILE"
|
||||||
|
echo "Launching mongod (dbpath=/data/db, log=$LOGFILE)..."
|
||||||
|
mongod --dbpath /data/db --fork --logpath "$LOGFILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
ready_check() {
|
||||||
|
if grep -q "Waiting for connections" "$LOGFILE" 2>/dev/null; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if command -v nc >/dev/null 2>&1; then
|
||||||
|
nc -z 127.0.0.1 27017 2>/dev/null && return 0
|
||||||
|
fi
|
||||||
|
if command -v mongosh >/dev/null 2>&1; then
|
||||||
|
mongosh --quiet --eval 'db.runCommand({ping:1})' >/dev/null 2>&1 && return 0 || true
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_ready() {
|
||||||
|
for ((i=1; i<=READY_CHECK_RETRIES; i++)); do
|
||||||
|
if ready_check; then
|
||||||
|
echo "mongod is ready (after $i checks)."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
sleep "$READY_CHECK_INTERVAL"
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Starting MongoDB with retries..."
|
||||||
|
for ((attempt=1; attempt<=MAX_START_TRIES; attempt++)); do
|
||||||
|
echo "Start attempt $attempt/$MAX_START_TRIES"
|
||||||
|
if start_mongod && wait_for_ready; then
|
||||||
|
tail -20 "$LOGFILE" || true
|
||||||
|
echo "MongoDB started successfully."
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( attempt == MAX_START_TRIES )); then
|
||||||
|
tail -40 "$LOGFILE" || true
|
||||||
|
die "MongoDB failed to start after $MAX_START_TRIES attempts"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Cleaning up before next attempt..."
|
||||||
|
cleaned_up=false
|
||||||
|
while IFS= read -r pid; do
|
||||||
|
if [ -n "$pid" ]; then
|
||||||
|
kill "$pid" || true
|
||||||
|
cleaned_up=true
|
||||||
|
fi
|
||||||
|
done < <(mongod_pid)
|
||||||
|
if [ "$cleaned_up" = true ]; then
|
||||||
|
sleep 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "post_start.sh completed successfully."
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
👋 Welcome to building a modern multi-tier application with GitHub Copilot agent mode!
|
||||||
|
|
||||||
|
You will build OctoFit Tracker using:
|
||||||
|
- Presentation tier: React 19
|
||||||
|
- Logic tier: Node.js + Express + TypeScript
|
||||||
|
- Data tier: MongoDB
|
||||||
|
|
||||||
|
Ports used in this exercise:
|
||||||
|
- 5173 (public)
|
||||||
|
- 8000 (public)
|
||||||
|
- 27017 (private)
|
||||||
|
|
||||||
|
📃 GitHub Copilot documentation: https://docs.github.com/en/copilot
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
applyTo: "octofit-tracker/backend/**"
|
||||||
|
---
|
||||||
|
# Octofit Tracker Logic + Data Tier Guidelines
|
||||||
|
|
||||||
|
## Logic tier (Node.js + Express + TypeScript)
|
||||||
|
|
||||||
|
- Build API routes under `/api/`.
|
||||||
|
- Keep API service on port `8000`.
|
||||||
|
- Use environment-aware Codespaces URLs via `CODESPACE_NAME`.
|
||||||
|
|
||||||
|
Example base URL logic:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const codespaceName = process.env.CODESPACE_NAME;
|
||||||
|
const baseUrl = codespaceName
|
||||||
|
? `https://${codespaceName}-8000.app.github.dev`
|
||||||
|
: 'http://localhost:8000';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Data tier (MongoDB + Mongoose)
|
||||||
|
|
||||||
|
- Use Mongoose models for users, teams, activities, leaderboard, and workouts.
|
||||||
|
- Connect to `octofit_db`.
|
||||||
|
- Validate endpoints with `curl` after wiring routes.
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
applyTo: "octofit-tracker/frontend/**"
|
||||||
|
---
|
||||||
|
# Octofit Tracker React Presentation Tier Guidelines
|
||||||
|
|
||||||
|
Use commands that target `octofit-tracker/frontend` without changing directories.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm create vite@latest octofit-tracker/frontend -- --template react
|
||||||
|
npm install --prefix octofit-tracker/frontend
|
||||||
|
npm install bootstrap react-router-dom --prefix octofit-tracker/frontend
|
||||||
|
```
|
||||||
|
|
||||||
|
Add Bootstrap CSS import at the top of `octofit-tracker/frontend/src/main.jsx`.
|
||||||
|
|
||||||
|
## Images
|
||||||
|
|
||||||
|
Use `docs/octofitapp-small.png` for the app logo.
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
applyTo: "**"
|
||||||
|
---
|
||||||
|
# Octofit Tracker Multi-tier Application Setup Guidelines
|
||||||
|
|
||||||
|
## Application goals
|
||||||
|
|
||||||
|
Build an Octofit Tracker **multi-tier application** with:
|
||||||
|
|
||||||
|
- User authentication and profiles
|
||||||
|
- Activity logging and tracking
|
||||||
|
- Team creation and management
|
||||||
|
- Competitive leaderboard
|
||||||
|
- Personalized workout suggestions
|
||||||
|
|
||||||
|
## Command execution rules
|
||||||
|
|
||||||
|
- Never change directories in commands.
|
||||||
|
- Always reference target paths directly.
|
||||||
|
|
||||||
|
## Forwarded ports
|
||||||
|
|
||||||
|
- 8000: public (logic/API tier)
|
||||||
|
- 5173: public (presentation tier)
|
||||||
|
- 27017: private (data tier)
|
||||||
|
|
||||||
|
Do not propose any other ports to forward or make public.
|
||||||
|
|
||||||
|
## Project structure
|
||||||
|
|
||||||
|
```text
|
||||||
|
octofit-tracker/
|
||||||
|
├── backend/
|
||||||
|
│ ├── src/
|
||||||
|
│ ├── package.json
|
||||||
|
│ └── tsconfig.json
|
||||||
|
└── frontend/
|
||||||
|
├── src/
|
||||||
|
└── package.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## Stack requirements
|
||||||
|
|
||||||
|
### Presentation tier
|
||||||
|
|
||||||
|
- React 19 with Vite
|
||||||
|
- react-router-dom for navigation
|
||||||
|
- bootstrap for styling
|
||||||
|
|
||||||
|
### Logic tier
|
||||||
|
|
||||||
|
- Node.js (LTS)
|
||||||
|
- Express
|
||||||
|
- TypeScript
|
||||||
|
|
||||||
|
### Data tier
|
||||||
|
|
||||||
|
- MongoDB (`mongodb-org`)
|
||||||
|
- Mongoose for data access
|
||||||
|
|
||||||
|
## MongoDB service expectations
|
||||||
|
|
||||||
|
- Always use `ps aux | grep mongod` to check whether mongod is running.
|
||||||
|
- `mongodb-org` is the official MongoDB package.
|
||||||
|
- `mongosh` is the official client tool.
|
||||||
|
- Use Mongoose models from the logic tier for schema/data work instead of ad-hoc raw scripts.
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
mode: 'agent'
|
||||||
|
model: GPT-5.5
|
||||||
|
description: 'Create the Node.js logic tier for the Octofit multi-tier application'
|
||||||
|
---
|
||||||
|
|
||||||
|
Create the logic tier in `octofit-tracker/backend` for the Octofit Tracker multi-tier application.
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
|
||||||
|
1. Do not change directories; use path-qualified commands.
|
||||||
|
2. Initialize a TypeScript Node.js API with Express.
|
||||||
|
3. Configure scripts for build/dev/start.
|
||||||
|
4. Add route handlers for:
|
||||||
|
- `/api/users/`
|
||||||
|
- `/api/teams/`
|
||||||
|
- `/api/activities/`
|
||||||
|
- `/api/leaderboard/`
|
||||||
|
- `/api/workouts/`
|
||||||
|
5. Keep server port on `8000`.
|
||||||
|
6. Add Codespaces-aware API URL support using `CODESPACE_NAME`.
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
mode: 'agent'
|
||||||
|
model: GPT-5.5
|
||||||
|
description: 'Configure MongoDB and seed octofit_db for the Octofit multi-tier application'
|
||||||
|
---
|
||||||
|
|
||||||
|
Set up and populate the data tier for `octofit-tracker/backend`.
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
|
||||||
|
1. Use MongoDB with Mongoose.
|
||||||
|
2. Use connection string for local MongoDB on port `27017` and database `octofit_db`.
|
||||||
|
3. Create Mongoose models for users, teams, activities, leaderboard, and workouts.
|
||||||
|
4. Add a seed script at `src/scripts/seed.ts`.
|
||||||
|
5. Include this help/description text in the seed script comments or logs:
|
||||||
|
`Seed the octofit_db database with test data`.
|
||||||
|
6. Insert realistic sample data for all collections.
|
||||||
|
7. Verify data creation with API route responses.
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
## Step 1: Prepare your modern multi-tier application exercise
|
||||||
|
|
||||||
|
Welcome to your **"Build applications with GitHub Copilot agent mode"** exercise! :robot:
|
||||||
|
|
||||||
|
In this exercise, you will build a **modern multi-tier application** for OctoFit Tracker:
|
||||||
|
|
||||||
|
- **Presentation tier:** React 19
|
||||||
|
- **Logic tier:** Node.js + Express + TypeScript
|
||||||
|
- **Data tier:** MongoDB
|
||||||
|
|
||||||
|
### :keyboard: Activity: Create and publish your working branch
|
||||||
|
|
||||||
|
1. Open your Codespace for your repository copy.
|
||||||
|
|
||||||
|
1. Open Copilot Chat and switch to **Agent** mode.
|
||||||
|
|
||||||
|
1. Run this prompt:
|
||||||
|
|
||||||
|
> 
|
||||||
|
>
|
||||||
|
> ```prompt
|
||||||
|
> Please create and publish a new Git branch called build-octofit-app
|
||||||
|
> ```
|
||||||
|
|
||||||
|
1. Confirm the active branch is `build-octofit-app`.
|
||||||
|
|
||||||
|
1. Wait for Mona to post the next step.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Having trouble? 🤷</summary><br/>
|
||||||
|
|
||||||
|
- Make sure the branch name is exactly `build-octofit-app`.
|
||||||
|
- Make sure the branch is pushed to your repository.
|
||||||
|
|
||||||
|
</details>
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
## Step 2: Initialize the modern multi-tier application stack
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> **Behind the scenes:** This exercise uses custom instruction files to guide Copilot for this multi-tier application setup.
|
||||||
|
|
||||||
|
In this step, you will initialize a modern **multi-tier application** foundation:
|
||||||
|
|
||||||
|
- Create `octofit-tracker/frontend` and `octofit-tracker/backend`.
|
||||||
|
- Initialize React 19 (presentation tier) with Vite.
|
||||||
|
- Initialize a Node.js + Express + TypeScript backend (logic tier).
|
||||||
|
- Add MongoDB support with Mongoose (data tier).
|
||||||
|
|
||||||
|
### :keyboard: Activity: Initialize frontend and backend package manifests
|
||||||
|
|
||||||
|
> 
|
||||||
|
>
|
||||||
|
> ```prompt
|
||||||
|
> Let's initialize the OctoFit Tracker modern multi-tier application.
|
||||||
|
>
|
||||||
|
> Follow the instructions exactly and execute step-by-step:
|
||||||
|
> - Create octofit-tracker/frontend and octofit-tracker/backend
|
||||||
|
> - Initialize React 19 in the frontend with Vite
|
||||||
|
> - Initialize backend package.json for Node.js + Express + TypeScript
|
||||||
|
> - Add mongoose for MongoDB data access
|
||||||
|
> - Keep ports at 5173 (frontend), 8000 (backend), and 27017 (MongoDB)
|
||||||
|
> ```
|
||||||
|
|
||||||
|
1. Commit and push to `build-octofit-app`.
|
||||||
|
|
||||||
|
1. Wait for Mona to check your work and post the next lesson.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Having trouble? 🤷</summary><br/>
|
||||||
|
|
||||||
|
Check these files exist and include expected dependencies:
|
||||||
|
|
||||||
|
- `octofit-tracker/frontend/package.json` with React 19.
|
||||||
|
- `octofit-tracker/backend/package.json` with `express` and `mongoose`.
|
||||||
|
|
||||||
|
</details>
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
## Step 3: Build the logic and data tiers for the multi-tier application
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> **Behind the scenes:** Custom instructions and prompt files guide Copilot while building the logic and data tiers.
|
||||||
|
|
||||||
|
In this step, you will implement the backend of the **multi-tier application**:
|
||||||
|
|
||||||
|
- Configure MongoDB connection for `octofit_db`.
|
||||||
|
- Create Express routes for users, teams, activities, leaderboard, and workouts.
|
||||||
|
- Add a seed script to populate test data.
|
||||||
|
|
||||||
|
### :keyboard: Activity: Scaffold the logic tier
|
||||||
|
|
||||||
|
Use this prompt file:
|
||||||
|
|
||||||
|
> 
|
||||||
|
>
|
||||||
|
> ```prompt
|
||||||
|
> /create-express-logic-tier
|
||||||
|
> ```
|
||||||
|
|
||||||
|
### :keyboard: Activity: Configure and seed the data tier
|
||||||
|
|
||||||
|
Use this prompt file:
|
||||||
|
|
||||||
|
> 
|
||||||
|
>
|
||||||
|
> ```prompt
|
||||||
|
> /init-populate-octofit_db
|
||||||
|
> ```
|
||||||
|
|
||||||
|
1. Commit and push your backend changes.
|
||||||
|
|
||||||
|
1. Wait for Mona to validate and unlock the next step.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Having trouble? 🤷</summary><br/>
|
||||||
|
|
||||||
|
Confirm these files include expected content:
|
||||||
|
|
||||||
|
- `octofit-tracker/backend/src/config/database.ts` includes `octofit_db` and `mongoose`.
|
||||||
|
- `octofit-tracker/backend/src/scripts/seed.ts` includes a seed command description.
|
||||||
|
|
||||||
|
</details>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
## Step 4: Wire API hosting for the multi-tier application
|
||||||
|
|
||||||
|
In this step, you will finalize API hosting for your **multi-tier application**:
|
||||||
|
|
||||||
|
- Keep backend API on port `8000`.
|
||||||
|
- Build Codespaces-aware API URL behavior using `$CODESPACE_NAME`.
|
||||||
|
- Validate endpoints with `curl`.
|
||||||
|
|
||||||
|
### :keyboard: Activity: Configure API base URL and host support
|
||||||
|
|
||||||
|
> 
|
||||||
|
>
|
||||||
|
> ```prompt
|
||||||
|
> Let's configure the Node.js API for Codespaces and localhost.
|
||||||
|
>
|
||||||
|
> - Backend runs on port 8000
|
||||||
|
> - Build API base URL with $CODESPACE_NAME when available:
|
||||||
|
> https://$CODESPACE_NAME-8000.app.github.dev
|
||||||
|
> - Keep localhost support when $CODESPACE_NAME is not set
|
||||||
|
> - Verify /api/users and /api/activities with curl
|
||||||
|
> ```
|
||||||
|
|
||||||
|
1. Commit and push your changes to `build-octofit-app`.
|
||||||
|
|
||||||
|
1. Wait for Mona to validate and share the next step.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Having trouble? 🤷</summary><br/>
|
||||||
|
|
||||||
|
Verify `octofit-tracker/backend/src/server.ts` includes:
|
||||||
|
|
||||||
|
- `CODESPACE_NAME`
|
||||||
|
- `-8000.app.github.dev`
|
||||||
|
|
||||||
|
</details>
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
## Step 5: Build the React presentation tier of the multi-tier application
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This step implements the **presentation tier** for your modern multi-tier application.
|
||||||
|
|
||||||
|
In this step, you will:
|
||||||
|
|
||||||
|
- Complete React 19 frontend components.
|
||||||
|
- Connect each view to the backend API routes.
|
||||||
|
- Use React Router for navigation.
|
||||||
|
|
||||||
|
### :keyboard: Activity: Implement frontend components and routing
|
||||||
|
|
||||||
|
> 
|
||||||
|
>
|
||||||
|
> ```prompt
|
||||||
|
> Let's update the React 19 presentation tier for this multi-tier application.
|
||||||
|
>
|
||||||
|
> - Update src/App.jsx and src/main.jsx
|
||||||
|
> - Update src/components/Activities.jsx
|
||||||
|
> - Update src/components/Leaderboard.jsx
|
||||||
|
> - Update src/components/Teams.jsx
|
||||||
|
> - Update src/components/Users.jsx
|
||||||
|
> - Update src/components/Workouts.jsx
|
||||||
|
> - Use react-router-dom for navigation
|
||||||
|
> - Use Vite environment variables via `import.meta.env`, for example `import.meta.env.VITE_CODESPACE_NAME`
|
||||||
|
> - Document that `VITE_CODESPACE_NAME` must be defined (for example in `.env.local`)
|
||||||
|
> - Use API endpoints under:
|
||||||
|
> https://${import.meta.env.VITE_CODESPACE_NAME}-8000.app.github.dev/api/[component]/
|
||||||
|
> - Add a safe fallback if `VITE_CODESPACE_NAME` is unset to avoid `https://undefined-8000...` URLs
|
||||||
|
> - Keep compatibility with paginated and array responses
|
||||||
|
> ```
|
||||||
|
|
||||||
|
### :keyboard: Activity: Run and verify the presentation tier
|
||||||
|
|
||||||
|
Run the React app with the Vite dev server (for example, `npm run dev`) and open port `5173`.
|
||||||
|
|
||||||
|
1. Commit and push your changes.
|
||||||
|
|
||||||
|
1. Wait for Mona to verify and post the final lesson.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Having trouble? 🤷</summary><br/>
|
||||||
|
|
||||||
|
Confirm these files include the expected endpoint paths:
|
||||||
|
|
||||||
|
- `Activities.jsx` -> `/api/activities/`
|
||||||
|
- `Leaderboard.jsx` -> `/api/leaderboard/`
|
||||||
|
- `Teams.jsx` -> `/api/teams/`
|
||||||
|
- `Users.jsx` -> `/api/users/`
|
||||||
|
- `Workouts.jsx` -> `/api/workouts/`
|
||||||
|
|
||||||
|
</details>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
## Step 6: Use Copilot on your multi-tier application pull request
|
||||||
|
|
||||||
|
Great job! You have implemented a modern **multi-tier application** with Copilot agent mode.
|
||||||
|
|
||||||
|
Now create and complete your pull request workflow.
|
||||||
|
|
||||||
|
### :keyboard: Activity: Open, summarize, and review your PR
|
||||||
|
|
||||||
|
1. Open your repository in a browser.
|
||||||
|
|
||||||
|
1. Create a pull request with:
|
||||||
|
- **base:** `main`
|
||||||
|
- **compare:** `build-octofit-app`
|
||||||
|
- **title:** `Modernize OctoFit multi-tier application stack`
|
||||||
|
|
||||||
|
1. Optionally use **Copilot Summary** for the PR description.
|
||||||
|
|
||||||
|
1. Optionally request a **Copilot code review**.
|
||||||
|
|
||||||
|
1. Merge the pull request.
|
||||||
|
|
||||||
|
1. Wait for Mona to post the final review.
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
## Review
|
||||||
|
|
||||||
|
_Congratulations, you've completed this exercise!_
|
||||||
|
|
||||||
|
You built and modernized a **multi-tier application** using GitHub Copilot agent mode.
|
||||||
|
|
||||||
|
### What you accomplished
|
||||||
|
|
||||||
|
- Prepared a Codespaces environment for a multi-tier application.
|
||||||
|
- Implemented a React 19 presentation tier.
|
||||||
|
- Built a Node.js + Express + TypeScript logic tier.
|
||||||
|
- Connected a MongoDB data tier with Mongoose.
|
||||||
|
- Practiced pull request summarization and review with Copilot.
|
||||||
|
|
||||||
|
### What's next?
|
||||||
|
|
||||||
|
- Add authentication and role-based authorization.
|
||||||
|
- Add tests for API routes and React components.
|
||||||
|
- Add CI checks for linting and automated tests.
|
||||||
|
- Explore other GitHub Skills exercises.
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
name: Step 0 # Start Exercise build-applications-w-GHCP-agent-mode
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
actions: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
STEP_1_FILE: ".github/steps/1-preparing.md"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
start_exercise:
|
||||||
|
if: |
|
||||||
|
!github.event.repository.is_template
|
||||||
|
name: Start Exercise
|
||||||
|
uses: skills/exercise-toolkit/.github/workflows/start-exercise.yml@v0.9.0
|
||||||
|
with:
|
||||||
|
exercise-title: "Build Applications with GitHub Copilot Agent Mode"
|
||||||
|
intro-message: |
|
||||||
|
"Welcome to the exciting world of GitHub Copilot agent mode! 🚀
|
||||||
|
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! 💻✨"
|
||||||
|
|
||||||
|
post_next_step_content:
|
||||||
|
name: Post next step content
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [start_exercise]
|
||||||
|
env:
|
||||||
|
ISSUE_NUMBER: ${{ needs.start_exercise.outputs.issue-number }}
|
||||||
|
ISSUE_REPOSITORY: ${{ github.repository }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Get response templates
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
repository: skills/exercise-toolkit
|
||||||
|
path: exercise-toolkit
|
||||||
|
ref: v0.9.0
|
||||||
|
|
||||||
|
- name: Create comment - add step content
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: ${{ env.STEP_1_FILE }}
|
||||||
|
vars: |
|
||||||
|
login: ${{ github.actor }}
|
||||||
|
full_repo_name: ${{ github.repository }}
|
||||||
|
|
||||||
|
- name: Create comment - watching for progress
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md
|
||||||
|
|
||||||
|
- name: Enable next step workflow
|
||||||
|
run: |
|
||||||
|
gh workflow enable "Step 1"
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
name: Step 1 # Preparing to use GHCP agent mode
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "build-octofit-app"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
actions: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
STEP_2_FILE: ".github/steps/2-application-initial-setup.md"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
find_exercise:
|
||||||
|
name: Find Exercise Issue
|
||||||
|
uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.9.0
|
||||||
|
|
||||||
|
post_next_step_content:
|
||||||
|
name: Post next step content
|
||||||
|
needs: [find_exercise]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
ISSUE_REPOSITORY: ${{ github.repository }}
|
||||||
|
ISSUE_NUMBER: ${{ needs.find_exercise.outputs.issue-number }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Get response templates
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
repository: skills/exercise-toolkit
|
||||||
|
path: exercise-toolkit
|
||||||
|
ref: v0.9.0
|
||||||
|
|
||||||
|
- name: Create comment - step finished
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/step-finished-prepare-next-step.md
|
||||||
|
vars: |
|
||||||
|
next_step_number: 2
|
||||||
|
|
||||||
|
- name: Create comment - add step content
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: ${{ env.STEP_2_FILE }}
|
||||||
|
|
||||||
|
- name: Create comment - watching for progress
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md
|
||||||
|
|
||||||
|
- name: Disable current workflow and enable next one
|
||||||
|
run: |
|
||||||
|
gh workflow disable "${{github.workflow}}"
|
||||||
|
gh workflow enable "Step 2"
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
name: Step 2 # octofit-tracker application initial setup
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "build-octofit-app"
|
||||||
|
paths:
|
||||||
|
- "octofit-tracker/frontend/package.json"
|
||||||
|
- "octofit-tracker/backend/package.json"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
actions: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
STEP_3_FILE: ".github/steps/3-django-project-setup.md"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
find_exercise:
|
||||||
|
name: Find Exercise Issue
|
||||||
|
uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.9.0
|
||||||
|
|
||||||
|
check_step_work:
|
||||||
|
name: Check step work
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [find_exercise]
|
||||||
|
env:
|
||||||
|
ISSUE_REPOSITORY: ${{ github.repository }}
|
||||||
|
ISSUE_NUMBER: ${{ needs.find_exercise.outputs.issue-number }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Get response templates
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
repository: skills/exercise-toolkit
|
||||||
|
path: exercise-toolkit
|
||||||
|
ref: v0.9.0
|
||||||
|
|
||||||
|
- name: Find last comment
|
||||||
|
id: find-last-comment
|
||||||
|
uses: peter-evans/find-comment@v3
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
direction: last
|
||||||
|
|
||||||
|
- name: Update comment - checking work
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
comment-id: ${{ steps.find-last-comment.outputs.comment-id }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/checking-work.md
|
||||||
|
edit-mode: replace
|
||||||
|
|
||||||
|
# START: Check practical exercise
|
||||||
|
|
||||||
|
- name: Check React 19 dependency
|
||||||
|
id: check-react-19
|
||||||
|
continue-on-error: true
|
||||||
|
uses: skills/action-keyphrase-checker@v2.0.0
|
||||||
|
with:
|
||||||
|
text-file: octofit-tracker/frontend/package.json
|
||||||
|
keyphrase: '"react": "\^19'
|
||||||
|
minimum-occurrences: 1
|
||||||
|
case-sensitive: false
|
||||||
|
|
||||||
|
- name: Check Express dependency
|
||||||
|
id: check-express
|
||||||
|
continue-on-error: true
|
||||||
|
uses: skills/action-keyphrase-checker@v2.0.0
|
||||||
|
with:
|
||||||
|
text-file: octofit-tracker/backend/package.json
|
||||||
|
keyphrase: '"express"'
|
||||||
|
minimum-occurrences: 1
|
||||||
|
case-sensitive: false
|
||||||
|
|
||||||
|
- name: Check Mongoose dependency
|
||||||
|
id: check-mongoose
|
||||||
|
continue-on-error: true
|
||||||
|
uses: skills/action-keyphrase-checker@v2.0.0
|
||||||
|
with:
|
||||||
|
text-file: octofit-tracker/backend/package.json
|
||||||
|
keyphrase: '"mongoose"'
|
||||||
|
minimum-occurrences: 1
|
||||||
|
case-sensitive: false
|
||||||
|
|
||||||
|
- name: Update comment - step results
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
comment-id: ${{ steps.find-last-comment.outputs.comment-id }}
|
||||||
|
edit-mode: replace
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/step-results-table.md
|
||||||
|
vars: |
|
||||||
|
step_number: 2
|
||||||
|
results_table:
|
||||||
|
- description: "Check frontend package.json for React 19"
|
||||||
|
passed: ${{ steps.check-react-19.outcome == 'success' }}
|
||||||
|
- description: "Check backend package.json for Express"
|
||||||
|
passed: ${{ steps.check-express.outcome == 'success' }}
|
||||||
|
- description: "Check backend package.json for Mongoose"
|
||||||
|
passed: ${{ steps.check-mongoose.outcome == 'success' }}
|
||||||
|
|
||||||
|
# END: Check practical exercise
|
||||||
|
|
||||||
|
- name: Fail job if not all checks passed
|
||||||
|
if: contains(steps.*.outcome, 'failure')
|
||||||
|
run: exit 1
|
||||||
|
|
||||||
|
post_next_step_content:
|
||||||
|
name: Post next step content
|
||||||
|
needs: [find_exercise, check_step_work]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
ISSUE_REPOSITORY: ${{ github.repository }}
|
||||||
|
ISSUE_NUMBER: ${{ needs.find_exercise.outputs.issue-number }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Get response templates
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
repository: skills/exercise-toolkit
|
||||||
|
path: exercise-toolkit
|
||||||
|
ref: v0.9.0
|
||||||
|
|
||||||
|
- name: Create comment - step finished
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/step-finished-prepare-next-step.md
|
||||||
|
vars: |
|
||||||
|
next_step_number: 3
|
||||||
|
|
||||||
|
- name: Create comment - add step content
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: ${{ env.STEP_3_FILE }}
|
||||||
|
|
||||||
|
- name: Create comment - watching for progress
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md
|
||||||
|
|
||||||
|
- name: Disable current workflow and enable next one
|
||||||
|
run: |
|
||||||
|
gh workflow disable "${{github.workflow}}"
|
||||||
|
gh workflow enable "Step 3"
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
name: Step 3 # Logic tier setup and MongoDB test data population
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "build-octofit-app"
|
||||||
|
paths:
|
||||||
|
- "octofit-tracker/backend/src/**"
|
||||||
|
- "octofit-tracker/backend/package.json"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
actions: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
STEP_4_FILE: ".github/steps/4-setup-django-rest-framework.md"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
find_exercise:
|
||||||
|
name: Find Exercise Issue
|
||||||
|
uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.9.0
|
||||||
|
|
||||||
|
check_step_work:
|
||||||
|
name: Check step work
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [find_exercise]
|
||||||
|
env:
|
||||||
|
ISSUE_REPOSITORY: ${{ github.repository }}
|
||||||
|
ISSUE_NUMBER: ${{ needs.find_exercise.outputs.issue-number }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Get response templates
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
repository: skills/exercise-toolkit
|
||||||
|
path: exercise-toolkit
|
||||||
|
ref: v0.9.0
|
||||||
|
|
||||||
|
- name: Find last comment
|
||||||
|
id: find-last-comment
|
||||||
|
uses: peter-evans/find-comment@v3
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
direction: last
|
||||||
|
|
||||||
|
- name: Update comment - checking work
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
comment-id: ${{ steps.find-last-comment.outputs.comment-id }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/checking-work.md
|
||||||
|
edit-mode: replace
|
||||||
|
|
||||||
|
# START: Check practical exercise
|
||||||
|
- name: Check database config file for octofit_db
|
||||||
|
id: check-octofit-db
|
||||||
|
continue-on-error: true
|
||||||
|
uses: skills/action-keyphrase-checker@v2.0.0
|
||||||
|
with:
|
||||||
|
text-file: octofit-tracker/backend/src/config/database.ts
|
||||||
|
keyphrase: 'octofit_db'
|
||||||
|
minimum-occurrences: 1
|
||||||
|
case-sensitive: false
|
||||||
|
|
||||||
|
- name: Check database config file for mongoose
|
||||||
|
id: check-mongoose-config
|
||||||
|
continue-on-error: true
|
||||||
|
uses: skills/action-keyphrase-checker@v2.0.0
|
||||||
|
with:
|
||||||
|
text-file: octofit-tracker/backend/src/config/database.ts
|
||||||
|
keyphrase: 'mongoose'
|
||||||
|
minimum-occurrences: 1
|
||||||
|
case-sensitive: false
|
||||||
|
|
||||||
|
- name: Check seed script description
|
||||||
|
id: check-seed-script
|
||||||
|
continue-on-error: true
|
||||||
|
uses: skills/action-keyphrase-checker@v2.0.0
|
||||||
|
with:
|
||||||
|
text-file: octofit-tracker/backend/src/scripts/seed.ts
|
||||||
|
keyphrase: 'Seed the octofit_db database with test data'
|
||||||
|
minimum-occurrences: 1
|
||||||
|
case-sensitive: false
|
||||||
|
|
||||||
|
- name: Update comment - step results
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
comment-id: ${{ steps.find-last-comment.outputs.comment-id }}
|
||||||
|
edit-mode: replace
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/step-results-table.md
|
||||||
|
vars: |
|
||||||
|
step_number: 3
|
||||||
|
results_table:
|
||||||
|
- description: "Check database.ts for octofit_db"
|
||||||
|
passed: ${{ steps.check-octofit-db.outcome == 'success' }}
|
||||||
|
- description: "Check database.ts for mongoose"
|
||||||
|
passed: ${{ steps.check-mongoose-config.outcome == 'success' }}
|
||||||
|
- description: "Check seed.ts for test data seed description"
|
||||||
|
passed: ${{ steps.check-seed-script.outcome == 'success' }}
|
||||||
|
|
||||||
|
# END: Check practical exercise
|
||||||
|
|
||||||
|
- name: Fail job if not all checks passed
|
||||||
|
if: contains(steps.*.outcome, 'failure')
|
||||||
|
run: exit 1
|
||||||
|
|
||||||
|
post_next_step_content:
|
||||||
|
name: Post next step content
|
||||||
|
needs: [find_exercise, check_step_work]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
ISSUE_REPOSITORY: ${{ github.repository }}
|
||||||
|
ISSUE_NUMBER: ${{ needs.find_exercise.outputs.issue-number }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Get response templates
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
repository: skills/exercise-toolkit
|
||||||
|
path: exercise-toolkit
|
||||||
|
ref: v0.9.0
|
||||||
|
|
||||||
|
- name: Create comment - step finished
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/step-finished-prepare-next-step.md
|
||||||
|
vars: |
|
||||||
|
next_step_number: 4
|
||||||
|
|
||||||
|
- name: Create comment - add step content
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: ${{ env.STEP_4_FILE }}
|
||||||
|
|
||||||
|
- name: Create comment - watching for progress
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md
|
||||||
|
|
||||||
|
- name: Disable current workflow and enable next one
|
||||||
|
run: |
|
||||||
|
gh workflow disable "${{github.workflow}}"
|
||||||
|
gh workflow enable "Step 4"
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
name: Step 4 # Setup API hosting for the logic tier
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "build-octofit-app"
|
||||||
|
paths:
|
||||||
|
- "octofit-tracker/backend/src/**"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
actions: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
STEP_5_FILE: ".github/steps/5-setup-frontend-react-framework.md"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
find_exercise:
|
||||||
|
name: Find Exercise Issue
|
||||||
|
uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.9.0
|
||||||
|
|
||||||
|
check_step_work:
|
||||||
|
name: Check step work
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [find_exercise]
|
||||||
|
env:
|
||||||
|
ISSUE_REPOSITORY: ${{ github.repository }}
|
||||||
|
ISSUE_NUMBER: ${{ needs.find_exercise.outputs.issue-number }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Get response templates
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
repository: skills/exercise-toolkit
|
||||||
|
path: exercise-toolkit
|
||||||
|
ref: v0.9.0
|
||||||
|
|
||||||
|
- name: Find last comment
|
||||||
|
id: find-last-comment
|
||||||
|
uses: peter-evans/find-comment@v3
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
direction: last
|
||||||
|
|
||||||
|
- name: Update comment - checking work
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
comment-id: ${{ steps.find-last-comment.outputs.comment-id }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/checking-work.md
|
||||||
|
edit-mode: replace
|
||||||
|
|
||||||
|
# START: Check practical exercise
|
||||||
|
|
||||||
|
- name: Check server.ts uses codespace env variable
|
||||||
|
id: check-codespace-name
|
||||||
|
continue-on-error: true
|
||||||
|
uses: skills/action-keyphrase-checker@v2.0.0
|
||||||
|
with:
|
||||||
|
text-file: octofit-tracker/backend/src/server.ts
|
||||||
|
keyphrase: 'CODESPACE_NAME'
|
||||||
|
minimum-occurrences: 1
|
||||||
|
case-sensitive: false
|
||||||
|
|
||||||
|
- name: Check server.ts includes codespace URL pattern
|
||||||
|
id: check-codespace-url
|
||||||
|
continue-on-error: true
|
||||||
|
uses: skills/action-keyphrase-checker@v2.0.0
|
||||||
|
with:
|
||||||
|
text-file: octofit-tracker/backend/src/server.ts
|
||||||
|
keyphrase: '-8000.app.github.dev'
|
||||||
|
minimum-occurrences: 1
|
||||||
|
case-sensitive: false
|
||||||
|
|
||||||
|
- name: Update comment - step results
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
comment-id: ${{ steps.find-last-comment.outputs.comment-id }}
|
||||||
|
edit-mode: replace
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/step-results-table.md
|
||||||
|
vars: |
|
||||||
|
step_number: 4
|
||||||
|
results_table:
|
||||||
|
- description: "Check server.ts for CODESPACE_NAME"
|
||||||
|
passed: ${{ steps.check-codespace-name.outcome == 'success' }}
|
||||||
|
- description: "Check server.ts for codespace URL"
|
||||||
|
passed: ${{ steps.check-codespace-url.outcome == 'success' }}
|
||||||
|
|
||||||
|
# END: Check practical exercise
|
||||||
|
|
||||||
|
- name: Fail job if not all checks passed
|
||||||
|
if: contains(steps.*.outcome, 'failure')
|
||||||
|
run: exit 1
|
||||||
|
|
||||||
|
post_next_step_content:
|
||||||
|
name: Post next step content
|
||||||
|
needs: [find_exercise, check_step_work]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
ISSUE_REPOSITORY: ${{ github.repository }}
|
||||||
|
ISSUE_NUMBER: ${{ needs.find_exercise.outputs.issue-number }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Get response templates
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
repository: skills/exercise-toolkit
|
||||||
|
path: exercise-toolkit
|
||||||
|
ref: v0.9.0
|
||||||
|
|
||||||
|
- name: Create comment - step finished
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/step-finished-prepare-next-step.md
|
||||||
|
vars: |
|
||||||
|
next_step_number: 5
|
||||||
|
|
||||||
|
- name: Create comment - add step content
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: ${{ env.STEP_5_FILE }}
|
||||||
|
|
||||||
|
- name: Create comment - watching for progress
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md
|
||||||
|
|
||||||
|
- name: Disable current workflow and enable next one
|
||||||
|
run: |
|
||||||
|
gh workflow disable "${{github.workflow}}"
|
||||||
|
gh workflow enable "Step 5"
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -0,0 +1,186 @@
|
|||||||
|
name: Step 5 # Setup the React presentation tier
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "build-octofit-app"
|
||||||
|
paths:
|
||||||
|
- "octofit-tracker/frontend/**"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
actions: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
STEP_6_FILE: ".github/steps/6-copilot-on-github.md"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
find_exercise:
|
||||||
|
name: Find Exercise Issue
|
||||||
|
uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.9.0
|
||||||
|
|
||||||
|
check_step_work:
|
||||||
|
name: Check step work
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [find_exercise]
|
||||||
|
env:
|
||||||
|
ISSUE_REPOSITORY: ${{ github.repository }}
|
||||||
|
ISSUE_NUMBER: ${{ needs.find_exercise.outputs.issue-number }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Get response templates
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
repository: skills/exercise-toolkit
|
||||||
|
path: exercise-toolkit
|
||||||
|
ref: v0.9.0
|
||||||
|
|
||||||
|
- name: Find last comment
|
||||||
|
id: find-last-comment
|
||||||
|
uses: peter-evans/find-comment@v3
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
direction: last
|
||||||
|
|
||||||
|
- name: Update comment - checking work
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
comment-id: ${{ steps.find-last-comment.outputs.comment-id }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/checking-work.md
|
||||||
|
edit-mode: replace
|
||||||
|
|
||||||
|
# START: Check practical exercise
|
||||||
|
|
||||||
|
- name: Check for codespace API endpoint in Activities.jsx
|
||||||
|
id: check-activities
|
||||||
|
continue-on-error: true
|
||||||
|
uses: skills/action-keyphrase-checker@v2.0.0
|
||||||
|
with:
|
||||||
|
text-file: octofit-tracker/frontend/src/components/Activities.jsx
|
||||||
|
keyphrase: '-8000.app.github.dev/api/activities'
|
||||||
|
minimum-occurrences: 1
|
||||||
|
case-sensitive: false
|
||||||
|
|
||||||
|
- name: Check for codespace API endpoint in Leaderboard.jsx
|
||||||
|
id: check-leaderboard
|
||||||
|
continue-on-error: true
|
||||||
|
uses: skills/action-keyphrase-checker@v2.0.0
|
||||||
|
with:
|
||||||
|
text-file: octofit-tracker/frontend/src/components/Leaderboard.jsx
|
||||||
|
keyphrase: '-8000.app.github.dev/api/leaderboard'
|
||||||
|
minimum-occurrences: 1
|
||||||
|
case-sensitive: false
|
||||||
|
|
||||||
|
- name: Check for codespace API endpoint in Teams.jsx
|
||||||
|
id: check-teams
|
||||||
|
continue-on-error: true
|
||||||
|
uses: skills/action-keyphrase-checker@v2.0.0
|
||||||
|
with:
|
||||||
|
text-file: octofit-tracker/frontend/src/components/Teams.jsx
|
||||||
|
keyphrase: '-8000.app.github.dev/api/teams'
|
||||||
|
minimum-occurrences: 1
|
||||||
|
case-sensitive: false
|
||||||
|
|
||||||
|
- name: Check for codespace API endpoint in Users.jsx
|
||||||
|
id: check-users
|
||||||
|
continue-on-error: true
|
||||||
|
uses: skills/action-keyphrase-checker@v2.0.0
|
||||||
|
with:
|
||||||
|
text-file: octofit-tracker/frontend/src/components/Users.jsx
|
||||||
|
keyphrase: '-8000.app.github.dev/api/users'
|
||||||
|
minimum-occurrences: 1
|
||||||
|
case-sensitive: false
|
||||||
|
|
||||||
|
- name: Check for codespace API endpoint in Workouts.jsx
|
||||||
|
id: check-workouts
|
||||||
|
continue-on-error: true
|
||||||
|
uses: skills/action-keyphrase-checker@v2.0.0
|
||||||
|
with:
|
||||||
|
text-file: octofit-tracker/frontend/src/components/Workouts.jsx
|
||||||
|
keyphrase: '-8000.app.github.dev/api/workouts'
|
||||||
|
minimum-occurrences: 1
|
||||||
|
case-sensitive: false
|
||||||
|
|
||||||
|
- name: Update comment - step results
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
comment-id: ${{ steps.find-last-comment.outputs.comment-id }}
|
||||||
|
edit-mode: replace
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/step-results-table.md
|
||||||
|
vars: |
|
||||||
|
step_number: 5
|
||||||
|
results_table:
|
||||||
|
- description: "Check activities for the API endpoint"
|
||||||
|
passed: ${{ steps.check-activities.outcome == 'success' }}
|
||||||
|
- description: "Check leaderboard for the API endpoint"
|
||||||
|
passed: ${{ steps.check-leaderboard.outcome == 'success' }}
|
||||||
|
- description: "Check teams for the API endpoint"
|
||||||
|
passed: ${{ steps.check-teams.outcome == 'success' }}
|
||||||
|
- description: "Check users for the API endpoint"
|
||||||
|
passed: ${{ steps.check-users.outcome == 'success' }}
|
||||||
|
- description: "Check workouts for the API endpoint"
|
||||||
|
passed: ${{ steps.check-workouts.outcome == 'success' }}
|
||||||
|
|
||||||
|
# END: Check practical exercise
|
||||||
|
|
||||||
|
- name: Fail job if not all checks passed
|
||||||
|
if: contains(steps.*.outcome, 'failure')
|
||||||
|
run: exit 1
|
||||||
|
|
||||||
|
post_next_step_content:
|
||||||
|
name: Post next step content
|
||||||
|
needs: [find_exercise, check_step_work]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
ISSUE_REPOSITORY: ${{ github.repository }}
|
||||||
|
ISSUE_NUMBER: ${{ needs.find_exercise.outputs.issue-number }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Get response templates
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
repository: skills/exercise-toolkit
|
||||||
|
path: exercise-toolkit
|
||||||
|
ref: v0.9.0
|
||||||
|
|
||||||
|
- name: Create comment - step finished
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/step-finished-prepare-next-step.md
|
||||||
|
vars: |
|
||||||
|
next_step_number: 6
|
||||||
|
|
||||||
|
- name: Create comment - add step content
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: ${{ env.STEP_6_FILE }}
|
||||||
|
|
||||||
|
- name: Create comment - watching for progress
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md
|
||||||
|
|
||||||
|
- name: Disable current workflow and enable next one
|
||||||
|
run: |
|
||||||
|
gh workflow disable "${{github.workflow}}"
|
||||||
|
gh workflow enable "Step 6"
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
name: Step 6 # Copilot on GitHub
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- "octofit-tracker/**"
|
||||||
|
types:
|
||||||
|
- closed
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
actions: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
REVIEW_FILE: ".github/steps/x-review.md"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
find_exercise:
|
||||||
|
name: Find Exercise Issue
|
||||||
|
uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.9.0
|
||||||
|
|
||||||
|
post_review_content:
|
||||||
|
name: Post review content
|
||||||
|
needs: [find_exercise]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
ISSUE_REPOSITORY: ${{ github.repository }}
|
||||||
|
ISSUE_NUMBER: ${{ needs.find_exercise.outputs.issue-number }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Get response templates
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
repository: skills/exercise-toolkit
|
||||||
|
path: exercise-toolkit
|
||||||
|
ref: v0.9.0
|
||||||
|
|
||||||
|
- name: Create comment - step finished - final review next
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: exercise-toolkit/markdown-templates/step-feedback/lesson-review.md
|
||||||
|
|
||||||
|
- name: Create comment - add review content
|
||||||
|
uses: GrantBirki/comment@v2.1.1
|
||||||
|
with:
|
||||||
|
repository: ${{ env.ISSUE_REPOSITORY }}
|
||||||
|
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||||
|
file: ${{ env.REVIEW_FILE }}
|
||||||
|
|
||||||
|
- name: Disable current workflow
|
||||||
|
run: gh workflow disable "${{github.workflow}}"
|
||||||
|
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.9.0
|
||||||
|
with:
|
||||||
|
issue-url: ${{ needs.find_exercise.outputs.issue-url }}
|
||||||
|
exercise-title: "Build Applications with GitHub Copilot Agent Mode"
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Virtual Environment
|
||||||
|
venv
|
||||||
|
|
||||||
|
# octofit tracker app
|
||||||
|
# octfit-tracker
|
||||||
|
|
||||||
|
# React node_modules
|
||||||
|
node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Python files
|
||||||
|
*.pyc
|
||||||
|
__pycache__/
|
||||||
Vendored
+38
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Launch Django Backend",
|
||||||
|
"type": "python",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/octofit-tracker/backend/manage.py",
|
||||||
|
"args": ["runserver", "0.0.0.0:8000"],
|
||||||
|
"django": true,
|
||||||
|
"justMyCode": true,
|
||||||
|
"python": "${workspaceFolder}/octofit-tracker/backend/venv/bin/python",
|
||||||
|
"env": {
|
||||||
|
"PYTHONPATH": "${workspaceFolder}/octofit-tracker/backend/venv/bin/python",
|
||||||
|
"VIRTUAL_ENV": "${workspaceFolder}/octofit-tracker/backend/venv",
|
||||||
|
"PATH": "${workspaceFolder}/octofit-tracker/backend/venv/bin:${env:PATH}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Launch Vite Frontend",
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"cwd": "${workspaceFolder}/octofit-tracker/frontend",
|
||||||
|
"runtimeExecutable": "npm",
|
||||||
|
"runtimeArgs": [
|
||||||
|
"run",
|
||||||
|
"dev",
|
||||||
|
"--",
|
||||||
|
"--host",
|
||||||
|
"0.0.0.0"
|
||||||
|
],
|
||||||
|
"port": 5173,
|
||||||
|
"env": {
|
||||||
|
"VITE_CODESPACE_NAME": "${env:CODESPACE_NAME}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2025 GitHub Skills
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# Build applications with GitHub Copilot agent mode
|
||||||
|
|
||||||
|
<!--  -->
|
||||||
|
<img src="https://github.com/user-attachments/assets/1b3ea5df-f18d-4ed8-9ae6-f96dc1861818" alt="octofit-tracker" width="300"/>
|
||||||
|
|
||||||
|
_Build an application with GitHub Copilot agent mode in less than an hour._
|
||||||
|
|
||||||
|
## Welcome
|
||||||
|
|
||||||
|
People love how GitHub Copilot helps them write code faster and with fewer errors.
|
||||||
|
But what if GitHub could create a multi-tier application with a presentation, logic, and data layers based on requirements written in natural language?
|
||||||
|
In this exercise, we will prompt GitHub Copilot agent mode to create a complete application.
|
||||||
|
|
||||||
|
- **Who is this for**: Intermediate developers familiar with GitHub Copilot, basic GitHub, and basic web development
|
||||||
|
- **What you'll learn**: We'll introduce GitHub Copilot agent mode and how to use it for application development.
|
||||||
|
- **What you'll build**: You'll use GitHub Copilot agent mode to create a fitness application as the gym teacher of a high school.
|
||||||
|
- **Prerequisites**: Skills Exercise: <a href="https://github.com/skills/getting-started-with-github-copilot">Getting Started with GitHub Copilot</a>.
|
||||||
|
- **How long**: This course takes less than one hour to complete.
|
||||||
|
|
||||||
|
In this exercise, you will:
|
||||||
|
|
||||||
|
1. Start up a preconfigured development environment for making a multi-tier application.
|
||||||
|
1. Prompt in GitHub Copilot Chat and select the edit tab and select agent mode from the edit/agent drop-down.
|
||||||
|
1. In this exercise I primarily used the latest default LLM.
|
||||||
|
1. Try other LLM models to see other output.
|
||||||
|
1. For each step open up a new Copilot Chat session by hitting the plus `+` icon in the Copilot Chat pane.
|
||||||
|
|
||||||
|
### How to start this exercise
|
||||||
|
|
||||||
|
Simply copy the exercise to your account, then give your favorite Octocat (Mona) **about 20 seconds** to prepare the first lesson, then **refresh the page**.
|
||||||
|
|
||||||
|
[](https://github.com/new?template_owner=skills&template_name=build-applications-w-copilot-agent-mode&owner=%40me&name=skills-build-applications-w-copilot-agent-mode&description=Exercise:+Build+applications+with+GitHub+Copilot+agent+mode&visibility=public)
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Having trouble? 🤷</summary><br/>
|
||||||
|
|
||||||
|
When copying the exercise, we recommend the following settings:
|
||||||
|
|
||||||
|
- For owner, choose your personal account or an organization to host the repository.
|
||||||
|
|
||||||
|
- We recommend creating a public repository, since private repositories will use Actions minutes.
|
||||||
|
|
||||||
|
If the exercise isn't ready in 20 seconds, please check the "Actions" tab of your repository (or visit `https://github.com/<YOUR-USERNAME>/<YOUR-REPO>/actions`).
|
||||||
|
|
||||||
|
- Check to see if a job is running. Sometimes it simply takes a bit longer.
|
||||||
|
|
||||||
|
- If the page shows a failed job, please submit an issue. Nice, you found a bug! 🐛
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
© 2025 GitHub • [Code of Conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/code_of_conduct.md) • [MIT License](https://gh.io/mit)
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
# Building a Fitness App with GitHub Copilot agent mode for Mergington High School
|
||||||
|
|
||||||
|
## OctoFit Tracker application story for Mergington High School
|
||||||
|
|
||||||
|
Paul Octo has been a physical education teacher at Mergington High School for over 8 years. Despite his enthusiasm and creative approach to gym class, he's been increasingly concerned about students' physical activity declining once they leave school grounds. Many students admitted they rarely exercised outside of the required PE classes.
|
||||||
|
After attending a professional development conference on "Technology Integration in Physical Education," Paul became inspired to create a solution. He wanted something that would:
|
||||||
|
|
||||||
|
1. Make fitness tracking fun and engaging
|
||||||
|
2. Create positive peer pressure through friendly competition
|
||||||
|
3. Allow him to monitor student progress remotely
|
||||||
|
4. Provide personalized guidance based on individual fitness levels
|
||||||
|
|
||||||
|
## The Birth of OctoFit Tracker
|
||||||
|
|
||||||
|
Paul initially sketched his idea on a notepad during lunch breaks. He envisioned an app where students could log workouts, earn achievement badges, and compete in monthly fitness challenges. However, as a PE teacher with only basic coding knowledge, the technical aspects seemed daunting.
|
||||||
|
That's when he approached Jessica Cat, the head of Mergington High's IT department. Jessica recommended using our repository instructions and prompts.
|
||||||
|
|
||||||
|
### Technical Planning Phase
|
||||||
|
|
||||||
|
Before starting development, Paul and Jessica carefully reviewed the OctoFit Tracker's instructions and prompts. This provided a solid foundation for OctoFit Tracker, ensuring compliance with technical standards and leveraging proven design patterns.
|
||||||
|
Together, Paul and the IT team identified key requirements for OctoFit Tracker:
|
||||||
|
|
||||||
|
### User Experience Goals
|
||||||
|
|
||||||
|
- Simple, intuitive interface designed specifically for teenagers
|
||||||
|
- Quick activity logging to minimize friction
|
||||||
|
- Social features that respect student privacy
|
||||||
|
- Gamification elements to maintain engagement
|
||||||
|
|
||||||
|
## Current Development Status
|
||||||
|
|
||||||
|
Paul and Jessica have set up a GitHub Codespace environment and are making remarkable progress with GitHub Copilot agent mode. The OctoFit Tracker prototype will include:
|
||||||
|
|
||||||
|
- A functional user registration system
|
||||||
|
- Basic activity logging for running, walking, and strength training
|
||||||
|
- The beginning framework for team competitions
|
||||||
|
- A simple dashboard showing student progress
|
||||||
|
|
||||||
|
## Next Steps for Paul
|
||||||
|
|
||||||
|
With the basic infrastructure in place, Paul is now focused on:
|
||||||
|
|
||||||
|
1. Developing an engaging point system that fairly compares different types of activities
|
||||||
|
2. Creating motivational challenges that appeal to different student interests
|
||||||
|
3. Building a notification system that encourages consistency without being intrusive
|
||||||
|
4. Designing reports that help him identify students who might need additional support or motivation
|
||||||
|
|
||||||
|
The IT department has been impressed with how GitHub Copilot agent mode has accelerated development, allowing Paul to focus on the educational aspects while the AI handles much of the technical implementation. Jessica Cat has been particularly pleased with how OctoFit Tracker leverages the custom instructions and prompt files.
|
||||||
|
|
||||||
|
### Workshop Overview
|
||||||
|
|
||||||
|
In this workshop, you'll:
|
||||||
|
|
||||||
|
1. Set up a development environment using **GitHub Codespaces**
|
||||||
|
2. Use **GitHub Copilot** to accelerate development across multiple technologies
|
||||||
|
3. Build key components of the **OctoFit Tracker** app with the help of Copilot agent mode
|
||||||
|
4. Learn best practices and prompting techniques for working with **GitHub Copilot agent mode**
|
||||||
|
|
||||||
|
### Application Features
|
||||||
|
|
||||||
|
**OctoFit Tracker** will include:
|
||||||
|
|
||||||
|
- User profiles
|
||||||
|
- Activity logging and tracking
|
||||||
|
- Team creation and management
|
||||||
|
- A competitive leaderboard
|
||||||
|
- Personalized workout suggestions
|
||||||
|
|
||||||
|
### GitHub Copilot Chat
|
||||||
|
|
||||||
|
- [Getting started with GitHub Copilot Chat](https://docs.github.com/en/copilot/how-tos/use-chat/get-started-with-chat?tool=vscode)
|
||||||
|
- [Use Chat in the IDE](https://docs.github.com/en/copilot/how-tos/use-chat/use-chat-in-ide?tool=vscode)
|
||||||
|
|
||||||
|
#### LLM models references
|
||||||
|
|
||||||
|
- [Supported AI models in GitHub Copilot](https://docs.github.com/en/copilot/reference/ai-models/supported-models)
|
||||||
|
- [AI model comparison](https://docs.github.com/en/copilot/reference/ai-models/model-comparison)
|
||||||
|
- [Changing the AI model for GitHub Copilot Chat](https://docs.github.com/en/copilot/how-tos/use-ai-models/change-the-chat-model?tool=vscode)
|
||||||
|
- [Changing the AI model for GitHub Copilot code completion](https://docs.github.com/en/copilot/how-tos/use-ai-models/change-the-completion-model?tool=vscode)
|
||||||
|
|
||||||
|
#### Prompt engineering
|
||||||
|
|
||||||
|
- [Prompt engineering for GitHub Copilot Chat](https://docs.github.com/en/copilot/concepts/prompt-engineering)
|
||||||
|
- [How to use GitHub Copilot: Prompts, tips, and use cases](https://github.blog/2023-06-20-how-to-write-better-prompts-for-github-copilot/)
|
||||||
|
- [Using GitHub Copilot in your IDE: Tips, tricks, and best practices](https://github.blog/2024-03-25-how-to-use-github-copilot-in-your-ide-tips-tricks-and-best-practices/)
|
||||||
|
|
||||||
|
### OctoFit tracker fitness application technology stack
|
||||||
|
|
||||||
|
We'll be using a modern web application stack:
|
||||||
|
|
||||||
|
- **Frontend**: React.js
|
||||||
|
- **Backend**: Python with Django REST API Framework
|
||||||
|
- **Database**: MongoDB
|
||||||
|
- **Development Environment**: GitHub Codespaces
|
||||||
|
|
||||||
|
### Workshop Structure
|
||||||
|
|
||||||
|
1. **Introduction**
|
||||||
|
- Overview of OctoFit Tracker app concept
|
||||||
|
- GitHub Copilot Chat models
|
||||||
|
|
||||||
|
2. **Setup of Prerequisites**
|
||||||
|
- Setting up GitHub Codespaces
|
||||||
|
- Ensure GitHub Copilot and Copilot Chat extensions are up to date
|
||||||
|
|
||||||
|
3. **Rapid Prototyping with GitHub Copilot agent mode**
|
||||||
|
- Creating project structure
|
||||||
|
- Generating boilerplate code
|
||||||
|
- Implementing basic models, serializers, urls, and views
|
||||||
|
|
||||||
|
4. **Building Core Features**
|
||||||
|
- Activity logging and tracking
|
||||||
|
- User profiles
|
||||||
|
- Team management
|
||||||
|
- Leaderboard functionality
|
||||||
|
|
||||||
|
5. **Frontend and Backend Development**
|
||||||
|
- Setting up React components
|
||||||
|
- Implementing responsive UI
|
||||||
|
- Connecting to backend APIs
|
||||||
|
- Python Django business logic
|
||||||
|
- MongoDB data layer
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 191 KiB |
Reference in New Issue
Block a user