Add Copilot Workshops sync workflow + Learning Hub i18n#2304
Add Copilot Workshops sync workflow + Learning Hub i18n#2304GeekTrainer wants to merge 1 commit into
Conversation
bb04f3b to
78cbd48
Compare
There was a problem hiding this comment.
Pull request overview
Adds Copilot Workshops synchronization and Learning Hub localization infrastructure, but also bundles many unrelated features and automation changes.
Changes:
- Adds workshop sync, i18n, and GitHub admonition rendering.
- Adds Canvas Extensions discovery and sample extensions.
- Adds unrelated skills, documentation, tools, and external-plugin workflows.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/copilot-workshops-sync.md |
Defines workshop synchronization. |
.github/workflows/copilot-workshops-sync.lock.yml |
Compiles the agentic workflow. |
website/astro.config.mjs |
Configures i18n, admonitions, and extensions. |
website/package.json |
Adds the admonitions dependency. |
website/package-lock.json |
Locks the new dependency. |
website/src/components/LanguageSelect.astro |
Conditionally displays language selection. |
website/src/pages/index.astro |
Adds the extensions category. |
website/src/pages/extensions.astro |
Adds the extensions listing page. |
website/src/scripts/pages/index.ts |
Loads extension counts. |
website/src/scripts/pages/extensions.ts |
Implements listing interactions. |
website/src/scripts/pages/extensions-render.ts |
Renders and sorts extensions. |
website/data/tools.yml |
Adds Ivy Tendril. |
eng/constants.mjs |
Defines the extensions directory. |
eng/generate-website-data.mjs |
Generates extension metadata. |
eng/update-readme.mjs |
Makes sorting locale-stable. |
extensions/accessibility-kanban/package.json |
Defines an extension package. |
extensions/color-orb/package.json |
Defines the Color Orb package. |
extensions/color-orb/package-lock.json |
Locks Color Orb dependencies. |
extensions/color-orb/extension.mjs |
Implements the Color Orb canvas. |
extensions/diagram-viewer/package.json |
Defines the diagram package. |
extensions/diagram-viewer/package-lock.json |
Locks diagram dependencies. |
extensions/feedback-themes/package.json |
Defines the feedback package. |
extensions/feedback-themes/package-lock.json |
Locks feedback dependencies. |
extensions/feedback-themes/extension.mjs |
Implements feedback theme exploration. |
extensions/feedback-themes/data/signals.json |
Supplies synthetic feedback data. |
extensions/gesture-review/package.json |
Defines the gesture-review package. |
extensions/gesture-review/package-lock.json |
Locks gesture-review dependencies. |
skills/namecheap/SKILL.md |
Adds Namecheap DNS guidance. |
skills/namecheap/references/namecheap-api.md |
Documents the Namecheap API. |
skills/conventional-branch/SKILL.md |
Adds branch-naming guidance. |
skills/from-the-other-side-anitta/SKILL.md |
Adds the Anitta profile. |
skills/from-the-other-side-quinn/SKILL.md |
Adds the Quinn profile. |
skills/from-the-other-side-wiggins/SKILL.md |
Adds the Wiggins profile. |
skills/rhino3d-scripts/SKILL.md |
Expands Rhino troubleshooting. |
skills/rhino3d-scripts/references/macros-and-loading.md |
Documents rhinocode. |
skills/adobe-illustrator-scripting/SKILL.md |
Expands external scripting guidance. |
skills/md-to-docx/scripts/md-to-docx.mjs |
Corrects entity decoding order. |
plugins/project-documenter/skills/md-to-docx/scripts/md-to-docx.mjs |
Mirrors entity decoding fix. |
plugins/ember/.github/plugin/plugin.json |
Registers three Ember skills. |
plugins/ember/README.md |
Documents the added profiles. |
plugins/ember/skills/from-the-other-side-anitta/SKILL.md |
Packages the Anitta profile. |
plugins/ember/skills/from-the-other-side-quinn/SKILL.md |
Packages the Quinn profile. |
plugins/ember/skills/from-the-other-side-wiggins/SKILL.md |
Packages the Wiggins profile. |
plugins/external.json |
Updates external plugin metadata. |
.github/plugin/marketplace.json |
Regenerates marketplace metadata. |
instructions/use-cliche-data-in-docs.instructions.md |
Adds context-aware placeholders. |
instructions/qa-engineering-best-practices.instructions.md |
Adds QA guidance. |
instructions/powershell-pester-5.instructions.md |
Clarifies runtime skipping. |
instructions/exclude-prompt-data.instructions.md |
Adds prompt-data exclusion rules. |
instructions/dotnet-framework.instructions.md |
Distinguishes project formats. |
hooks/secrets-scanner/scan-secrets.sh |
Broadens app-token matching. |
docs/README.skills.md |
Registers new skills. |
docs/README.plugins.md |
Updates Ember item count. |
docs/README.instructions.md |
Registers new instructions. |
CONTRIBUTING.md |
Documents plugin quality gates. |
AGENTS.md |
Updates external-plugin workflow guidance. |
.github/workflows/skill-check.yml |
Makes changed-file handling safer. |
.github/workflows/external-plugin-rerun-intake-command.yml |
Adds quality-gate reruns. |
.github/workflows/external-plugin-rereview-command.yml |
Adds command reactions. |
.github/workflows/external-plugin-quality-gates.yml |
Runs external-plugin gates. |
.github/workflows/external-plugin-mark-ready-command.yml |
Adds maintainer override handling. |
.github/workflows/external-plugin-intake.yml |
Integrates quality-gate state. |
.github/workflows/external-plugin-approval-command.yml |
Extends approval automation. |
eng/external-plugin-validation.mjs |
Updates recognized manifest paths. |
eng/external-plugin-intake-state.mjs |
Adds submitter-fixes state. |
.github/extensions/external-plugins-board/package.json |
Defines board dependencies. |
.github/extensions/external-plugins-board/package-lock.json |
Locks board dependencies. |
.github/aw/actions-lock.json |
Locks additional workflow actions. |
Review details
Files not reviewed (1)
- website/package-lock.json: Generated file
- Files reviewed: 4/6 changed files
- Comments generated: 2
- Review effort level: Medium
| - `lastUpdated:` — today's date in `YYYY-MM-DD` format (bump only on pages whose mirrored content changed; otherwise preserve the existing value) | ||
| - **GitHub admonitions.** The website renders GitHub admonition syntax (`> [!NOTE]`, `> [!TIP]`, `> [!IMPORTANT]`, `> [!WARNING]`, `> [!CAUTION]`) via a remark plugin, so **preserve admonitions exactly as written upstream** — do not convert them to Starlight `:::` asides and do not strip the `[!...]` markers. Keep the marker on its own `>`-prefixed line with the body on subsequent `>`-prefixed lines. | ||
| - **Image paths.** Rewrite upstream relative image references to site-absolute paths under `/images/learning-hub/copilot-workshops/`. Upstream uses a relative `_images/` reference whose depth depends on the file's location: English harness pages use `../_images/<file>.png`, while localized pages (which sit one directory deeper under `docs/<locale>/<harness>/`) use `../../_images/<file>.png`. **Collapse any leading run of `../` segments** before `_images/` — i.e. rewrite `(../)+_images/<file>` to `/images/learning-hub/copilot-workshops/<file>` regardless of how many `../` precede it (verify no stray `..//images/...` remains). Copy the referenced image files into `website/public/images/learning-hub/copilot-workshops/`. Localized pages reuse the same English image files and paths. | ||
| - **Internal course links.** Rewrite upstream intra-course links so they resolve on the website. Reference-style relative links like `0-prerequisites/`, `vscode/`, or `../cli/3-generating-code/` must point at the local mirror routes under `/learning-hub/copilot-workshops/<harness>/<lesson>/` (with a trailing slash, matching the site's `trailingSlash: always` setting). An overview link that upstream targets a harness folder (e.g. `vscode/`) maps to `/learning-hub/copilot-workshops/vscode/`. Preserve reference-style link definitions when upstream uses them. For localized pages, use the same root (unprefixed) target paths — Starlight rewrites them for the active locale automatically. |
There was a problem hiding this comment.
Good catch — you're right. I confirmed in the Starlight docs that locale prefixing only happens through the .astro helpers, not for absolute links in Markdown body content, so my original wording would've sent translated lessons back to the English routes. Reworked the instruction to require locale-prefixed targets (/es-es/learning-hub/copilot-workshops/...) on localized pages, with relative links as the alternative. Fixed in 615d26f.
|
|
||
| ```json | ||
| { | ||
| "last_synced_sha": "<latest commit SHA from github-samples/copilot-workshops@main>", |
There was a problem hiding this comment.
Agreed, this was a real footgun. Updated the workflow so the no-op path can't rely on the cached SHA alone — Step 1 now has to independently verify the checked-out mirror actually matches upstream before short-circuiting, and I added a note in Step 5 that last_synced_sha is an optimization hint, not proof of a merge. So a closed/rejected PR no longer leaves the mirror permanently stale. Fixed in 615d26f.
Set up the infrastructure to mirror the Copilot Workshops course into the Learning Hub: an agentic sync workflow, GitHub admonition rendering, and Starlight i18n with a translation-aware language picker. No course content yet — the workflow imports it on first run. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9e1d1a4c-a422-4cae-8ea7-b3d5171f58e3
78cbd48 to
615d26f
Compare
aaronpowell
left a comment
There was a problem hiding this comment.
The staged branch is now legacy and we target main.
I've retargeted the PR and I think I got everywhere in the workflow. You'll need to regenerate the YAML though.
| create-pull-request: | ||
| labels: [automated-update, learning-hub, copilot-workshops] | ||
| title-prefix: "[bot] " | ||
| base-branch: staged |
There was a problem hiding this comment.
The staged branch is now legacy (I should delete it), we target main.
| base-branch: staged | |
| base-branch: main |
|
|
||
| ## Step 6 — Open a pull request | ||
|
|
||
| Create a pull request with your changes using the `create-pull-request` safe output. Use `staged` as the base branch for all work related to this workflow, and never branch from `main`. The PR body must include: |
There was a problem hiding this comment.
| Create a pull request with your changes using the `create-pull-request` safe output. Use `staged` as the base branch for all work related to this workflow, and never branch from `main`. The PR body must include: | |
| Create a pull request with your changes using the `create-pull-request` safe output. Use `main` as the base branch for all work related to this workflow. The PR body must include: |
| - Preserve GitHub admonition syntax exactly; the site renders it natively. | ||
| - Only mirror localized files that actually exist upstream; rely on Starlight's fallback for the rest, and never fabricate translations. | ||
| - Keep the course source-faithful; avoid summaries or interpretive rewrites. | ||
| - Use `staged` as the base branch for any branch or PR created by this workflow; never branch from `main`. |
There was a problem hiding this comment.
| - Use `staged` as the base branch for any branch or PR created by this workflow; never branch from `main`. |
|
I'm just going to create a fresh PR |
|
Replaced by #2325, which targets |
This sets up the plumbing to mirror the "Hands-on with GitHub Copilot's agents" workshop from github-samples/copilot-workshops into the Learning Hub, the same way we already mirror Copilot CLI for Beginners.
Important: this PR is infrastructure + the sync workflow only. It does not add any course content. The content gets imported by the workflow's first run, which opens its own PR for review.
This workflow needs to be run manually once this lands on
stagedto do the initial content import — someone will need to trigger it viaworkflow_dispatch(Actions → "Copilot Workshops Content Sync" → Run workflow). It won't import anything on its own until the first scheduled run otherwise.What's in here
.github/workflows/copilot-workshops-sync.md+ compiled.lock.yml). Runs weekly, reads fromgithub-samples/copilot-workshops@main, and opens a PR againststagedwhen the upstream course changes. First run does a full import. It's a source-faithful mirror, no rewriting or summarizing the course.> [!NOTE]/> [!TIP]etc. everywhere, and our site had no support for it. Added theremark-github-admonitions-to-directivesplugin so those render as proper Starlight asides, same as they look on github.com.About the language picker
I didn't want a language dropdown showing up on every doc page across the site, since most content here is English-only. So there's a small override (
src/components/LanguageSelect.astro) that only shows the picker on pages that actually have a translation. Right now that means it's hidden everywhere, because no translated content exists yet. Once the workshop content lands, the picker will show up only on those pages.Under the hood Starlight still generates /es-es/... fallback routes for all docs (that's just how its i18n works), but nothing links to them and the picker never surfaces them until real translations exist.