catalog: import full platform engineering product catalog - #10
Merged
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ctural fields in PQF normalization Preserve product_type, ownership/squad, source, lifecycle, composed_of, context_refs in normalize_pqf_product; include documentation_url fallback/lookup in normalize_docs_product. Keep existing service_level->target_medal mapping and exclusions for deployments/communication. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…use built-in generics, clearer variable name\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…af'; add tests for default root and invalid override Fixes Task 3 reviewer findings Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…icalize id when checking overrides in classify_product_role; add tests \nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…legacy/canonical override keys both directions\n\nDefine lookup precedence: exact product id -> canonical id -> legacy id. Honor overrides deterministically and validate values.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…hip.squad equivalent and make field mapping source-driven Fixes: build_gap_report false-positive for UI ownership; build_field_mapping_report uses docs_fields input Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…uff I001 and E501 in Task 4 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…licit empty docs_fields\n\nFollow-up fixes for Task 4: keep mapped ui_field names even when missing from UI fields, and treat an explicit empty docs_fields as a deliberate source-driven input.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…o-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…squad ownership and other excluded fields; expose DOCS_PRODUCTS_DIR override; regenerate artifact\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…xplicit empty docs_fields in mapping Load PQF schema fields from config/schemas/product.schema.json and parse UI Product interface from ui/src/types.ts when provided. Pass explicit (even empty) docs_fields through to build_field_mapping_report. Add parsing helpers and tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rrors\n\n- Makefile: pass --pqf-schema-path and --ui-types-path to tools/generate_catalog_discovery.py so gap detection uses authoritative schema and UI type inputs\n- tools/generate_catalog_discovery.py: fail fast when explicit schema/ui paths are provided and parsing fails (do not swallow exceptions)\n- Regenerated discovery artifact (may be partial if docs dataset unavailable)\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add temporary tools-based catalog import workflow and import all current products from platform-engineering-docs into products/. Includes monorepo subpath extraction, discovery refresh, and validation updates for the expanded catalog. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
|
Prevent PR branch workflow runs from attempting to push generated artifacts to main, which now fails repository signed-commit rules. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds a single target to run lint + format-check + test + test-ui locally, exactly matching what the CI 'Python (lint + format + tests)' job runs. Previously only 'make lint' was being run locally before pushing, missing the separate 'make format-check' step and causing repeated CI failures from formatting violations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Based on GitHub repo topics (platform-engineering, product-*, squad-*): matrix.yaml: - Add maubot (canonical/maubot-operator) to composed_of — PE-owned, product-matrix, squad-amer topic confirms it's a matrix subproduct - Add irc-bridge (canonical/irc-bridge-operator) to composed_of — same - Remove both from context_refs (they weren't context-only dependencies) - smtp-integrator stays context_ref (product-mail-server topic, different owner) 12-factor.yaml: - Move paas-charm (canonical/paas-charm) from context_refs to composed_of It's a PE charm (product-12-factor, squad-emea topic) httprequest-lego-provider.yaml: - Remove self-referencing context_ref (own repo was listed as a dependency) indico.yaml: - Remove 3 duplicate context_refs pointing to canonical/indico-operator (already the main composed_of component as indico-charm) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
compute-metrics was triggering on every push to any branch that touched products/**, scorers/**, engine/**, or config/**. This caused 10+ full runs on the PR branch today, each invoking the LLM documentation scorer for all 34 products — a significant OpenRouter cost. Push trigger is now restricted to main. The workflow still runs: - Nightly (cron) - On merge to main (push to main with path filter) - Manually (workflow_dispatch) PR branches should use make ci-check locally and the CI lint/test job, not the expensive compute pipeline. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…h trigger The root problem this morning was not that compute-metrics ran on PR branches, but that 10+ runs executed sequentially — each paying LLM cost for all 34 products before the next fix commit even started. Proper fix: concurrency group scoped to branch + event type, with cancel-in-progress=true for push/dispatch events. When a new commit arrives, any running scorer jobs for that branch are cancelled and only the latest runs to completion. The nightly schedule run uses a unique group (includes run_id) so it is never cancelled by concurrent pushes. This restores the ability to see full computed results on a PR when tweaking scorer logic, medal thresholds, or product definitions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
context_refs were all labelled 'Context only — not scored by this team' regardless of whether the dependency was a PE-owned product (smtp-integrator, saml-integrator, nginx-ingress-integrator) or a truly external dependency (postgresql, redis, s3). Now the UI auto-detects at render time whether a context_ref's repo matches any product in the portfolio (directly or via a leaf's source): - Match found → 'Also scored by this team' with a link to that product page - No match → 'External dependencies — not scored by this team' No schema or data changes needed — the classification is derived entirely from the portfolio data already present. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace flat list with three visually distinct tiers: - Sub-products: 4-column CSS grid (medal | name | type chip | repo), bold section label. Medal badge for each sub-product gives an at-a-glance quality signal without having to navigate into each one. - Also scored by this team: compact inline pill row with medals and links to the PE product pages. Thin border-top separator. - External dependencies: compact inline row with repo links. Lightest visual weight since these don't affect the medal. The vertical rhythm and section label weight now clearly signals sub-products as primary, PE dependencies as secondary, external as footnote. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Previously, every inline sub-product in composed_of required its own target_medal field — always a copy of the parent's. This was fragile: raising a product's target required updating all its sub-products too, and a mismatch would cause drift to fire at different thresholds on the leaf page vs the root page. New rule: - Inline sub-products (defined under composed_of) have NO target_medal. They inherit from their parent root at engine evaluation time. - Standalone products (their own *.yaml, referenced via ref:) keep their own target_medal — they have independent quality accountability. Changes: - config/schemas/product.schema.json: removed target_medal from inline ComposedEntry required + properties (additionalProperties:false makes it a schema error to include it now) - products/*.yaml (33 files): stripped target_medal from all inline entries - engine/graph.py: ProductNode.target_medal is now str | None for inline nodes; both resolve_leaf_units functions substitute the parent root's target when target_medal is None - engine/assemble.py: same substitution before passing to compute_leaf_product - Tests: updated fixtures, added 4 new tests covering inheritance behaviour Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The PR preview pages were showing all products as Unrated because the compute-metrics workflow ran scorers and regenerated portfolio.json but only committed the artifacts back on main. On PR branches the computed data was uploaded to the GHA artifact store and then discarded. Fix: allow commit-artifacts to run on any push/dispatch event (not just main) by checking event_name != schedule instead of the branch name. The checkout now uses github.ref so it targets the triggering branch. The [skip ci] tag in the commit message prevents re-trigger loops. Schedule runs are excluded — they always target main and are handled by the existing nightly flow. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… fresh data on PR builds - Revert commit-artifacts to only run on main branch - Add workflow_run trigger to deploy-pages to catch compute-metrics completions - Download engine-artifacts from compute-metrics run to get fresh portfolio.json - Keeps PR branches clean (no automated commits) while ensuring PR previews show fresh medals This solves the 'unrated' issue on PR previews without causing merge conflicts on PR branch development. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove workflow_run approach (limited for PR branches in GitHub Actions) - Add pull_request trigger to deploy-pages - Always run engine to generate fresh portfolio.json before build - Only deploy to gh-pages on main (PR builds still generate fresh data for preview) - Fixes 'unrated' issue on PR previews by ensuring fresh medal computation Also fix: improve Dependencies section column proportions - Change grid from '6rem 1fr auto auto' to 'auto 1fr minmax(80px, auto) minmax(120px, auto)' - Medal badge now uses auto width instead of fixed 6rem - Product name properly handles long text with ellipsis - Type label and repo link have minimum widths for better alignment - Fixes column width layout issues in Dependencies panel Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Changes: - compute-metrics.yml: Remove main-only restriction on commit-artifacts job - Now commits to all branches where compute-metrics runs - Uses [skip ci] in commit message to prevent workflow re-triggering - deploy-pages.yml: Simplify to only deploy main to GitHub Pages - Remove complex workflow_run and pull_request triggers - Deploy only runs on main push events This ensures: - PR branches get fresh computed artifacts and portfolio.json - [skip ci] flag prevents merge conflicts from re-triggering workflows - PR previews automatically show fresh medals from the compute-metrics run - Main deployment is clean and simple Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add pull_request trigger with same path filters as push - This makes compute-metrics show up as a status check on PRs - Only commits artifacts on push events (not on pull_request) - PR preview will show fresh medals when relevant files change This ensures: - PR shows 'compute-metrics' running as a status check - PR cannot be merged until compute-metrics completes successfully - Fresh medals appear in PR preview Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tifacts Changes: - Replace pull_request trigger with workflow_run (after compute-metrics) - Download fresh engine-artifacts from compute-metrics run - Use fresh portfolio.json and computed/ data instead of stale branch versions - Only deploy if compute-metrics succeeded - Filter to only PRs (github.event.workflow_run.event == 'pull_request') Flow: 1. Developer pushes changes to PR branch 2. compute-metrics runs (shows in PR status checks) ✓ 3. When compute-metrics succeeds, preview.yml auto-triggers ✓ 4. Preview downloads fresh artifacts and rebuilds ✓ 5. PR preview shows fresh medals at https://canonical.github.io/pqf/pr-preview/pr-10/ Removed cleanup-preview job since PR closing will naturally stop preview generation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Allows manual triggering of PR preview builds if workflow_run event doesn't fire reliably. Supports providing explicit run_id or using latest PR compute-metrics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Skip PR preview deployment on forks (which don't have write permissions to the canonical/pqf gh-pages branch). Build succeeds but deployment is skipped with helpful message. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The preview workflow needs write permissions to push to gh-pages branch. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…mport The platform-engineering-docs catalog import overwrote 8 existing product YAMLs, stripping PQF-specific fields (allure_report_url, target_medal overrides). Without allure_report_url, the test_verification scorer returns 0% coverage and all these products compute as 'unrated' instead of their actual medal. Restored for: - discourse (discourse-k8s sub-product) - matrix (synapse sub-product, also restored target_medal: gold) - mattermost (mattermost-charm sub-product) - wazuh (wazuh-server sub-product) - indico (indico-charm sub-product) - jenkins (jenkins-k8s sub-product) - netbox (netbox-k8s sub-product) - wordpress-k8s (wordpress-k8s-charm sub-product) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nature requirements On branches with required signed commits, the github-actions[bot] unsigned commits are rejected. This should not fail the whole workflow since the engine-artifacts are already uploaded before this job runs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The workflow_run event only fires from the default branch, making it useless for PR previews. Instead: 1. compute-metrics.yml: After a successful pull_request run, fires a repository_dispatch event with run_id, pr_number, and head_branch. 2. preview.yml: Now responds to repository_dispatch (preview-pr type) and workflow_dispatch (for manual triggers). Both accept run_id and pr_number as inputs, fixing the missing PR number that caused deployment to 'pr-preview/pr-' instead of 'pr-preview/pr-10'. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
repository_dispatch hits rate limits with GITHUB_TOKEN. Use gh workflow run instead, which uses workflow_dispatch. Also add actions:write permission to compute-metrics so it can dispatch workflow events. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…spatch GITHUB_TOKEN cannot trigger workflow_dispatch events on other workflows (GitHub security restriction). Instead, fold the PR preview build directly into compute-metrics as a 'build-preview' job that runs after run-engine for pull_request events. This eliminates the cross-workflow dispatch entirely: - compute-metrics: runs scorers → engine → deploys preview (on pull_request) - preview.yml: kept for manual workflow_dispatch if needed Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
On PRs with many products, running all 111 scorers in parallel exhausts the GITHUB_TOKEN rate limit (1000 req/hr per repo). Products scored after the limit is hit return all-false values -> everything appears unrated. Changes: - On pull_request events: detect changed products via git diff Unchanged products reuse their committed computed/*.json file Only changed/new products are rescored - max-parallel: 10 to limit concurrent API load on push/schedule runs - fetch-depth: 0 so git diff can compare against base branch This ensures PR previews show accurate medals for the existing products while only incurring scorer costs for truly changed product definitions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PR-scoped GITHUB_TOKENs can fail cross-repo documentation lookups even for public repos, which made existing bronze products like discourse and wazuh show as unrated in PR artifacts. Retry public GitHub content requests without auth when the authenticated request returns 401/403/404. Also update the matrix integration test to match the restored gold target. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Constrain the dependency repo column and opt shrinkable cells into min-width: 0 so grid items can ellipsize instead of forcing awkward column sizing in some browser/layout combinations. Add a regression test covering the narrow-browser row styles. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR imports the complete current Platform Engineering product catalog from internal docs into PQF product definitions, and adds temporary migration tooling to keep imports repeatable until source-of-truth cutover is complete.
What changed
canonical/platform-engineering-docs:data/productsintoproducts/*.yamltools/fetch_platform_engineering_docs_products.pytools/import_platform_engineering_docs_products.pycatalog-discovery-fetchcatalog-import-productscatalog-discovery-reportdocs/superpowers/artifacts/2026-07-20-product-catalog-discovery.jsonsource.subpathfrom GitHub tree paths)engine/__tests__/test_import_platform_engineering_docs_products.py12-factor)Result
Discovery now reports full parity with current docs catalog:
docs_count: 34pqf_count: 34missing_in_pqf: []Temporary migration boundary (intentional)
Docs fetch/import logic is isolated in
tools/+ dedicated Make targets and is not part of normal engine scoring flow.This is temporary and designed for clean removal after cutover.
Validation
make catalog-import-products✅make catalog-discovery-report✅make lint✅make test✅ (180 passed)make test-ui✅ (70 passed)Known migration assumptions
ownership.squad(+ stakeholder names where available)Follow-up checklist (post-cutover cleanup)
tools/fetch_platform_engineering_docs_products.pytools/import_platform_engineering_docs_products.pycatalog-discovery-fetch,catalog-import-products)