name: Build and Deploy PMCP Course
on:
push:
branches: [ main ]
paths:
- 'pmcp-course/**'
- '.github/workflows/course.yml'
pull_request:
branches: [ main ]
paths:
- 'pmcp-course/**'
- '.github/workflows/course.yml'
release:
types: [published]
workflow_dispatch:
permissions:
contents: write
concurrency:
group: "course-build"
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
- name: Install mdBook
run: |
curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.40/mdbook-v0.4.40-x86_64-unknown-linux-gnu.tar.gz | tar -xz
chmod +x mdbook
sudo mv mdbook /usr/local/bin/
- name: Install mdbook-quiz
run: |
cargo install mdbook-quiz --locked || echo "mdbook-quiz installation failed, continuing without quiz support"
- name: Install mdbook-exercises
run: |
cargo install mdbook-exercises --locked || echo "mdbook-exercises installation failed, continuing without exercise support"
- name: Build Course Book
run: |
cd pmcp-course
mdbook build
- name: Upload book artifact
uses: actions/upload-artifact@v7
with:
name: course-book
path: pmcp-course/book
retention-days: 7
package-content:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Create course content package
run: |
# Package content (excluding book output)
# Structure: part1-foundations/, exercises/, quizzes/, metadata.toml
# The transform strips pmcp-course/src/ to create flat structure matching metadata.toml paths
tar -czf course-content.tar.gz \
--transform 's,^pmcp-course/src/,,' \
--transform 's,^pmcp-course/,,' \
pmcp-course/src/ \
pmcp-course/metadata.toml
# Show package contents
echo "Package contents:"
tar -tzf course-content.tar.gz | head -50
# Show package size
ls -lh course-content.tar.gz
- name: Upload content artifact
uses: actions/upload-artifact@v7
with:
name: course-content
path: course-content.tar.gz
retention-days: 30
upload-to-release:
if: github.event_name == 'release'
needs: [build, package-content]
runs-on: ubuntu-latest
steps:
- name: Download content artifact
uses: actions/download-artifact@v8
with:
name: course-content
- name: Rename with version
run: |
mv course-content.tar.gz course-content-${{ github.ref_name }}.tar.gz
ls -lh course-content-*.tar.gz
- name: Upload to release
uses: softprops/action-gh-release@v2
with:
files: course-content-${{ github.ref_name }}.tar.gz
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
validate-examples:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo
uses: Swatinem/rust-cache@v2
with:
workspaces: "examples/27-course-server-minimal"
- name: Build course-server-minimal example
run: |
cd examples/27-course-server-minimal
cargo build
- name: Test content loading
run: |
cd examples/27-course-server-minimal
CONTENT_DIR=../../pmcp-course/src cargo build
echo "Content loading validated"