Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ Uniformity, clarity, and ease of use are paramount across all infrastructures an
- `/`: Root directory containing the main files and folders. Bicep configuration is stored in `bicepconfig.json`.
- The following folders are all at the root level:
- `assets/`: Draw.io diagrams, SVG exports, and images. Static assets such as these should be placed here. Architecture diagrams should be placed in the /diagrams subfolder.
- `docs/`: Source for the public GitHub Pages landing page. See the *GitHub Pages Site* section below for upkeep rules.
- `infrastructure/`: Contains Jupyter notebooks for setting up various API Management infrastructures. When modifying samples, these notebooks should not need to be modified.
- `samples/`: Various policy and scenario samples that can be applied to the infrastructures.
- `setup/`: General setup scripts and configurations for the repository and dev environment setup.
Expand Down Expand Up @@ -371,10 +372,27 @@ Match the heading emojis, heading levels, and section ordering exactly. If a sec
- Document expected behavior for edge cases and error handling.
- Write unit tests for functions and classes, following language-specific testing frameworks.

## GitHub Pages Site

The public landing page at <https://azure-samples.github.io/Apim-Samples/> is built from `docs/index.html` by `.github/workflows/github-pages.yml` on every push to `main`. The page intentionally mirrors a subset of the root `README.md` (infrastructure cards, sample cards, quick-start steps) so that visitors get a polished overview without cloning the repo.

**Treat `docs/index.html` as a downstream consumer of the README.** When you change any of the following, update the landing page in the same PR:

| Change | Update required in `docs/index.html` | Also update |
|---|---|---|
| Add / remove / rename an **infrastructure** | Add / remove / rename the matching `.infra-card` **and** the matching `ListItem` in the JSON-LD `ItemList` (in `<head>`). Update the infrastructure count in the first `.value-card` if it still says "Five". | Add / remove the SVG copy line in `.github/workflows/github-pages.yml`. |
| Add / remove / rename a **sample** | Add / remove / rename the matching `.sample-card` **and** the matching `ListItem` in the JSON-LD `ItemList`. | — |
| Change a sample's **supported infrastructures** | Update the `.infra-tag` text on that sample's card. | — |
| Change the **quick-start flow** in the root README | Update the four `.step` items. | — |
| Rename or replace an **architecture SVG** in `assets/diagrams/` | — | Update the matching `cp` line in `.github/workflows/github-pages.yml`. |

Check `docs/README.md` for local preview instructions and styling notes. The page is deliberately plain static HTML + an external stylesheet (`docs/styles.css`), with no executable JavaScript and no build tooling, so that it cannot rot due to a transitive npm dependency. The only `<script>` tag is the JSON-LD structured-data block, which must stay inline because search-engine crawlers do not reliably follow external JSON-LD references. Keep it that way unless there is a compelling reason to add a build step.

## Required before each commit
- Ensure all code is well-documented and follows the guidelines in this file.
- Ensure that Jupyter notebooks do not contain any cell output.
- Ensure that Jupyter notebooks have `index` assigned to `1` in the first cell.
- If the change touches the infrastructure list, sample list, quick-start steps, or architecture SVGs, ensure `docs/index.html` (and the asset copy step in `.github/workflows/github-pages.yml` where relevant) has been updated to match.

## Jupyter Notebook Instructions

Expand Down
121 changes: 121 additions & 0 deletions .github/workflows/github-pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
name: GitHub Pages

# Publishes the static landing page at https://azure-samples.github.io/Apim-Samples/
# The site source lives in /docs and pulls images from /assets at build time.
# See docs/README.md for local preview instructions and the upkeep checklist.

on:
workflow_dispatch:
push:
branches: [ main ]
paths:
# Only rebuild when something that actually lands on the page changes.
- 'docs/**'
- 'assets/APIM-Samples.png'
- 'assets/APIM-Samples-Slide-Deck.html'
- 'assets/favicon-*.png'
- 'assets/apple-touch-icon.png'
- 'assets/android-chrome-*.png'
- 'assets/site.webmanifest'
- 'assets/diagrams/*.svg'
- 'setup/export_presentation.py'
- '.github/workflows/github-pages.yml'

# Top-level default is read-only. The deploy job elevates only what GitHub
# Pages needs (pages:write + id-token:write for the OIDC deploy token).
permissions:
contents: read

# Only one Pages deployment at a time. Newer pushes supersede in-flight ones,
# but do not cancel a deploy that is already rolling out.
concurrency:
group: github-pages
cancel-in-progress: false

jobs:
build:
name: Build site
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Configure Pages
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0

# Build the self-contained slide deck (all images inlined) so it can be
# served as a single file at /slide-deck.html. The export script is
# stdlib-only, so the runner's pre-installed Python is sufficient.
- name: Export self-contained slide deck
run: python3 setup/export_presentation.py

# The HTML references images at ./assets/... — stage them next to
# index.html so the uploaded artifact is entirely self-contained.
# Diagram SVGs are renamed to short, URL-safe slugs in the process.
- name: Stage site artifact
run: |
set -euo pipefail

mkdir -p _site/assets/diagrams

cp docs/index.html _site/index.html
cp docs/styles.css _site/styles.css
cp docs/robots.txt _site/robots.txt
cp docs/sitemap.xml _site/sitemap.xml

# Self-contained slide deck (built by the previous step)
cp build/APIM-Samples-Slide-Deck.html _site/slide-deck.html

# Brand assets
cp assets/APIM-Samples.png _site/assets/apim-samples-logo.png

# Favicon set + web app manifest. All six land flat in _site/assets/
# because site.webmanifest resolves its icon src paths relative to
# the manifest URL, not the page -- the android-chrome PNGs must be
# siblings of the manifest file.
cp assets/apple-touch-icon.png _site/assets/apple-touch-icon.png
cp assets/favicon-32x32.png _site/assets/favicon-32x32.png
cp assets/favicon-16x16.png _site/assets/favicon-16x16.png
cp assets/site.webmanifest _site/assets/site.webmanifest
cp assets/android-chrome-192x192.png _site/assets/android-chrome-192x192.png
cp assets/android-chrome-512x512.png _site/assets/android-chrome-512x512.png

# Architecture diagrams (slugified -> matches <img src> in index.html)
cp "assets/diagrams/Simple API Management Architecture.svg" \
_site/assets/diagrams/simple-apim.svg
cp "assets/diagrams/API Management & Container Apps Architecture.svg" \
_site/assets/diagrams/apim-aca.svg
cp "assets/diagrams/Azure Front Door, API Management & Container Apps Architecture.svg" \
_site/assets/diagrams/afd-apim-pe.svg
cp "assets/diagrams/Azure Application Gateway, API Management & Container Apps Architecture.svg" \
_site/assets/diagrams/appgw-apim-pe.svg
cp "assets/diagrams/Azure Application Gateway, API Management & Container Apps Architecture VNet.svg" \
_site/assets/diagrams/appgw-apim.svg

# github.io does not need Jekyll processing for a plain HTML site.
touch _site/.nojekyll

echo "Staged artifact contents:"
find _site -type f -printf ' %p\n'

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0
with:
path: _site

deploy:
name: Deploy site
needs: build
runs-on: ubuntu-latest
permissions:
pages: write # to push to the Pages deployment
id-token: write # to mint the OIDC token actions/deploy-pages needs
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ labs-in-progress/

# Build exports
/build/
/_site/

# Misc
*.log
Expand Down
8 changes: 7 additions & 1 deletion assets/APIM-Samples-Slide-Deck.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@
<meta name="release-approved" content="true" />
<meta name="approval-date" content="2026-02-26" />
<title>Azure API Management Samples - Presentation</title>
<link rel="icon" type="image/png" href="favicon.png" />
<!-- Favicon set. On the published site the exported deck lands at
_site/slide-deck.html (same directory level as index.html), so the
same ./assets/... paths resolve correctly. -->
<link rel="apple-touch-icon" sizes="180x180" href="./assets/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="./assets/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="./assets/favicon-16x16.png" />
<link rel="manifest" href="./assets/site.webmanifest" />
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }

Expand Down
Binary file added assets/android-chrome-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/android-chrome-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/favicon.ico
Binary file not shown.
19 changes: 19 additions & 0 deletions assets/site.webmanifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"background_color": "#ffffff",
"display": "standalone",
"icons": [
{
"sizes": "192x192",
"src": "android-chrome-192x192.png",
"type": "image/png"
},
{
"sizes": "512x512",
"src": "android-chrome-512x512.png",
"type": "image/png"
}
],
"name": "Azure API Management Samples",
"short_name": "APIM Samples",
"theme_color": "#0078D4"
}
66 changes: 66 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# GitHub Pages Site

This folder contains the source for the public landing page at
**<https://azure-samples.github.io/Apim-Samples/>**.

## How it works

| Piece | Role |
|---|---|
| `docs/index.html` | The page markup, structured data, and meta tags. CSS is externalised to `styles.css`; there is no executable JavaScript. |
| `docs/styles.css` | All visual rules for the landing page. Referenced by `index.html` via `<link rel="stylesheet">`. |
| `docs/robots.txt` | Permissive crawler policy plus a pointer to the sitemap. |
| `docs/sitemap.xml` | Single-URL sitemap. Deep links live on github.com and are out of scope for this origin. |
| `.github/workflows/github-pages.yml` | Assembles and publishes the site on every push to `main`. |
| `assets/` (repo root) | The workflow copies the logo, favicons, and architecture SVGs from here into the published artifact. `index.html` references them at `./assets/...`. |
| `assets/APIM-Samples-Slide-Deck.html` | The workflow runs `setup/export_presentation.py` to inline this deck's images and stages the result at `/slide-deck.html`. |

There is **no JavaScript framework, no bundler, and no npm install**. That is deliberate: the page changes rarely, and plain static HTML + CSS means the publish workflow cannot break due to a transitive package update. The only `<script>` in `index.html` is the JSON-LD structured-data block, which must remain inline because search-engine crawlers do not reliably follow external JSON-LD references.

## Previewing locally

From the Developer CLI (`./start.ps1` on Windows, `./start.sh` on macOS/Linux), choose:

```
w) Serve & view GitHub Pages website (auto-opens browser)
```

This runs `setup/serve_website.py`, which stages `_site/` exactly as the workflow does (including the self-contained slide deck), starts a local HTTP server on port 7800, and opens your browser. `_site/` is removed when you stop the server with Ctrl+C.

If you need to invoke it directly:

```bash
uv run python setup/serve_website.py # default port 7800
uv run python setup/serve_website.py 7801 # custom port
```

The staging logic in `serve_website.py` is the single local source of truth. If the workflow's copy step changes, update `stage_site()` to match so local preview stays faithful.

## Keeping the page current

The page intentionally duplicates a small amount of content from the root `README.md` (infrastructure list, sample list, quick-start steps). **When those change in the README, change them here too.**

Agents and contributors should treat the following as the sync checklist:

- **New infrastructure added** → add an `.infra-card` in the *Infrastructures* section of `index.html`, add a `ListItem` to the JSON-LD `ItemList` in the `<head>`, add its SVG to the copy step in `github-pages.yml`, and update the count in the value-prop card if it still says "Five".
- **New sample added** → add a `.sample-card` in the *Samples* section of `index.html` **and** a `ListItem` to the JSON-LD `ItemList`.
- **Sample or infrastructure removed or renamed** → remove or rename the matching card and any asset mapping in the workflow.
- **Quick-start flow changes** → update the four `.step` items.

This checklist is also enforced by `.github/copilot-instructions.md` so that GitHub Copilot will prompt for these updates when reviewing related PRs.

## Design notes

- Colour tokens (`--brand-blue`, `--accent-cyan`, …) mirror `assets/APIM-Samples-Slide-Deck.html` so the repo has one visual identity.
- WCAG 2.0 AA contrast targets: body text on white is `#24292f` (≈ 13.6:1), dim text on the deep-blue footer is `rgba(255,255,255,0.88)` (≈ 10.4:1).
- No emoji variation selectors are used, in line with the repo-wide rule.
- `prefers-reduced-motion` disables every transition for users who ask for that.
- Card hover lifts, the pill CTA button, and the shine sweep animation are adapted from the [APIM Love](https://aka.ms/apimlove) landing page, recoloured to this repo's palette. The shine sweep is suppressed under `prefers-reduced-motion`.

## SEO notes

The `<head>` carries a JSON-LD `@graph` with three nodes. `WebSite` gives search engines a canonical display name. `SoftwareSourceCode` declares the license, language stack, and the GitHub repository URL so the code repo and this landing page are understood as the same entity. `ItemList` enumerates every infrastructure and sample by name and URL — this is what drives sitelinks beneath the main search result.

The `ItemList` is the one piece that **must** stay in lock-step with the visible cards. If they drift, the search-result sitelinks will advertise folders that no longer exist. Validate after editing by pasting the page URL into <https://search.google.com/test/rich-results>.

`<lastmod>` is deliberately absent from `sitemap.xml`. GitHub Pages sets an accurate `Last-Modified` HTTP header from the artifact timestamp, and a hand-edited date would be stale within days.
Loading