Skip to content

Add Copilot Workshops sync workflow + Learning Hub i18n#2304

Closed
GeekTrainer wants to merge 1 commit into
github:mainfrom
GeekTrainer:geektrainer/explore-cli-beginners-publishing
Closed

Add Copilot Workshops sync workflow + Learning Hub i18n#2304
GeekTrainer wants to merge 1 commit into
github:mainfrom
GeekTrainer:geektrainer/explore-cli-beginners-publishing

Conversation

@GeekTrainer

Copy link
Copy Markdown
Contributor

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 staged to do the initial content import — someone will need to trigger it via workflow_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

  • The sync workflow (.github/workflows/copilot-workshops-sync.md + compiled .lock.yml). Runs weekly, reads from github-samples/copilot-workshops@main, and opens a PR against staged when the upstream course changes. First run does a full import. It's a source-faithful mirror, no rewriting or summarizing the course.
  • GitHub admonitions support. The upstream content uses > [!NOTE] / > [!TIP] etc. everywhere, and our site had no support for it. Added the remark-github-admonitions-to-directives plugin so those render as proper Starlight asides, same as they look on github.com.
  • Starlight i18n. The upstream repo ships localized content (es-es, ja-jp, ko-kr, pt-br, zh-cn), so I turned on Starlight's i18n with English as the root locale. Existing English URLs are unchanged.

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.

Copilot AI review requested due to automatic review settings July 15, 2026 21:17
@GeekTrainer
GeekTrainer requested a review from aaronpowell as a code owner July 15, 2026 21:17
@github-actions github-actions Bot added canvas-extension PR touches canvas extensions external-plugin Public external plugin submission hooks PR touches hooks instructions PR touches instructions new-submission PR adds at least one new contribution plugin PR touches plugins skills PR touches skills website-update PR touches website content or code workflow PR touches workflow automation labels Jul 15, 2026
@GeekTrainer
GeekTrainer force-pushed the geektrainer/explore-cli-beginners-publishing branch from bb04f3b to 78cbd48 Compare July 15, 2026 21:23
@github-actions github-actions Bot removed skills PR touches skills plugin PR touches plugins instructions PR touches instructions external-plugin Public external plugin submission hooks PR touches hooks canvas-extension PR touches canvas extensions labels Jul 15, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
@GeekTrainer
GeekTrainer force-pushed the geektrainer/explore-cli-beginners-publishing branch from 78cbd48 to 615d26f Compare July 15, 2026 21:30
aaronpowell
aaronpowell previously approved these changes Jul 15, 2026
@aaronpowell
aaronpowell changed the base branch from staged to main July 15, 2026 23:15
@aaronpowell
aaronpowell dismissed their stale review July 15, 2026 23:15

The base branch was changed.

@aaronpowell aaronpowell left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The staged branch is now legacy (I should delete it), we target main.

Suggested change
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:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Use `staged` as the base branch for any branch or PR created by this workflow; never branch from `main`.

@GeekTrainer

Copy link
Copy Markdown
Contributor Author

I'm just going to create a fresh PR

@GeekTrainer

Copy link
Copy Markdown
Contributor Author

Replaced by #2325, which targets main (the staged branch is now legacy per @aaronpowell). The review feedback from here — the base-branch change, the localized-link fix, and the sync-cache fix — all carried over into #2325.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new-submission PR adds at least one new contribution website-update PR touches website content or code workflow PR touches workflow automation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants