Skip to content

🗺️ M365 Roadmap Tracker

Live at: aguidetocloud.com/m365-roadmap/ Repo: susanthgit/m365-roadmap Built: April 10, 2026 Cost: $0/month (GitHub Actions Free + Azure SWA Free + Azure OpenAI ~$0.01/day)


What It Does

An automated tracker that pulls all ~1,900 items from Microsoft's official M365 roadmap API, detects changes daily, generates AI summaries, and displays everything in an "Amber Command" dark dashboard — complete with delay detection, favourites, RSS feed, and CSV export.

Think of it like having a personal radar that watches the Microsoft 365 roadmap for you and highlights what changed overnight.


Architecture Overview

┌───────────────────────────────────────────────────────────┐
│                GitHub Actions (daily at 5:00 UTC)          │
├───────────────────────────────────────────────────────────┤
│                                                           │
│  ┌────────────────┐  ┌──────────────┐  ┌───────────────┐ │
│  │fetch_roadmap.py│─▶│ summarise.py │─▶│generate_data  │ │
│  │  API + changes │  │ GPT-4o mini  │  │  .py          │ │
│  └────────────────┘  └──────────────┘  └───────────────┘ │
│         │                   │                  │          │
│   items.json          summaries.json     latest.json      │
│   previous_state.json cache.json         weekly/monthly   │
│   changelog.json                         feed.xml         │
├───────────────────────────────────────────────────────────┤
│   Clone main site repo → copy data → hugo build → deploy  │
└───────────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────┐
│            aguidetocloud.com/m365-roadmap/                 │
│                                                           │
│  ┌───────────┐  ┌────────────┐  ┌──────────────────────┐ │
│  │roadmap.js │  │roadmap.css │  │m365-roadmap/list.html│ │
│  │  ~260 loc │  │  ~165 loc  │  │Hugo template          │ │
│  └───────────┘  └────────────┘  └──────────────────────┘ │
│                                                           │
│  "Amber Command" palette: #E5A00D gold on #141118 dark    │
└───────────────────────────────────────────────────────────┘

Data Source

Microsoft Roadmap API — free, no auth required:

https://www.microsoft.com/releasecommunications/api/v1/m365

Returns all ~1,900 roadmap items as JSON. Updated by Microsoft daily. The pipeline makes a single GET request with a custom User-Agent: M365RoadmapTracker/1.0 (aguidetocloud.com).


Pipeline Scripts

1. fetch_roadmap.py

Feature Detail
API call Single GET to Microsoft roadmap API (timeout: 30s)
Change detection Compares each item against site/previous_state.json
Change types new, status_changed, date_changed, updated
Content hash md5(title + description + status + GA dates) for meaningful change detection
Delay flagging If GA date < current month AND status ≠ Launched/Cancelled → is_delayed = true
Changelog Accumulates changes into site/changelog.json with timestamps
First run Suppresses all change flags (treats everything as baseline)
Output site/items.json, site/previous_state.json, site/changelog.json

2. summarise.py

Feature Detail
Model Azure OpenAI gpt-4o-mini
Endpoint ainews-openai.openai.azure.com (shared with AI News)
Auth OIDC → Azure AD token (same service principal as AI News)
Cache key item.id + md5(description)[:12] — only re-summarises when content changes
Cache file site/summaries_cache.json
Batch size 10 items per API call
Temperature 0.2
Max tokens 200 × batch size
Fallback Single-item mode if batch parse fails; cache-only mode if no token

3. generate_data.py

Feature Detail
Daily archive site/data/YYYY-MM-DD.json (raw item snapshots)
Index files site/latest.json, site/weekly.json, site/monthly.json
RSS feed site/feed.xml (100 items max, changed first then active)
latest.json shape generated_at, total_items, active_items, summarised, changes_summary, product_categories, status_counts, items

GitHub Actions Workflow

File: .github/workflows/daily-roadmap.yml (~98 lines)

Schedule: Daily at 5:00 UTC
Triggers: cron + manual dispatch

Steps:
1. Checkout repo
2. Setup Python 3.12
3. Install requirements
4. Run fetch_roadmap.py
5. Azure OIDC login (azure/login@v2)
6. Get Azure OpenAI token
7. Run summarise.py
8. Run generate_data.py
9. Commit site/ back to pipeline repo
10. Clone main site repo → copy data → hugo build → swa deploy
11. On failure → create GitHub Issue

Shared OIDC Service Principal

Uses the same ainews service principal as AI News:

  • Client ID: 51b70f10-db98-4c14-84ef-2ca661e51b6d
  • Federated credential: m365-roadmap-github-actions-oidc
  • Scoped to: Azure OpenAI resource (ainews-openai)

Frontend Implementation

Hugo Templates

Template Purpose
layouts/m365-roadmap/list.html Main page — search, status/product filters, RSS/CSV links
layouts/m365-roadmap-category/list.html Category SEO pages — pre-filtered by roadmap_filter, CollectionPage JSON-LD

JavaScript — roadmap.js (~260 lines)

Feature How it works
Data source Fetches /data/roadmap/latest.json
sessionStorage cache Key: rdmap_v7, caches full JSON if < 2MB, 30-min freshness
Product filter Dropdown populated from product_categories in JSON
Category chips Horizontal bar with per-category item counts
Status filter Dropdown — "In Progress" excludes Launched + Cancelled
Search Matches title + AI summary + products
AI summaries Rendered inline in each row if present
Pagination PAGE_SIZE = 50, "Load more (N remaining)" button
Favourites localStorage key rdmap_favourites — star toggle per item
CSV export Client-side generation: ID,Title,Status,Product,GA Date,Delayed,Summary,URL
URL state Reads/writes ?product=, ?status=, ?q= for shareable views
Category pages Respects window.__roadmapCategoryFilter for pre-filtering
Keyboard / focuses search box

CSS — roadmap.css (~165 lines)

Element Detail
Accent colour Gold #E5A00D
Background #1a1510#141118 gradient
Cards #1C1924 bg, #2A2533 borders
Text #E8E4ED primary, #8B8594 muted
Chips Horizontal scroll on overflow
Mobile @media (max-width: 768px) — stacked controls, 1-column rows
CSS namespace .rdmap-* classes throughout

SEO Category Landing Pages

11 pages under content/m365-roadmap/:

Page Product Filter
/m365-roadmap/copilot/ Copilot
/m365-roadmap/teams/ Teams
/m365-roadmap/outlook/ Outlook
/m365-roadmap/sharepoint/ SharePoint
/m365-roadmap/office-apps/ Office Apps
/m365-roadmap/purview/ Purview
/m365-roadmap/intune/ Intune
/m365-roadmap/viva/ Viva
/m365-roadmap/entra/ Entra
/m365-roadmap/admin/ Admin
/m365-roadmap/edge-media/ Edge & Media

Each uses type: "m365-roadmap-category" + roadmap_filter param in front matter.


Key Design Decisions

Decision Rationale
"Amber Command" palette Military radar aesthetic — gold on charcoal conveys authority + monitoring
Same OIDC as AI News One service principal for both pipelines — simpler governance
Hash-based summary cache Only re-summarise items whose content actually changed — saves API costs
Delay flagging Automatically highlights items past their GA date — useful for customer conversations
Change detection Customers want to know "what changed since yesterday" — changelog answers this
sessionStorage v7 Bump CACHE_VERSION when changing JSON schema to invalidate stale cached data

Maintenance

Task How
Force a refresh Trigger daily-roadmap.yml manually via GitHub Actions
Bump cache version Edit CACHE_VERSION in roadmap.js when JSON schema changes
Add a category page Create content/m365-roadmap/<slug>/_index.md with type: "m365-roadmap-category"
Check for failures Look at GitHub Issues in m365-roadmap repo (auto-created on failure)
Update OIDC Same service principal as AI News → Federated credentials in Entra ID
Cache headers staticwebapp.config.json sets /data/roadmap/* to max-age=1800 (30 min)

Last updated: 11 April 2026