diff --git a/.github/workflows/redirects.yml b/.github/workflows/redirects.yml new file mode 100644 index 0000000..8a44333 --- /dev/null +++ b/.github/workflows/redirects.yml @@ -0,0 +1,20 @@ +name: Live redirect checks + +on: + workflow_dispatch: + schedule: + - cron: "43 8 * * 2" + +permissions: + contents: read + +jobs: + redirects: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Check out repository + uses: actions/checkout@v6 + + - name: Check deployed redirects and canonical destinations + run: python3 scripts/check-redirects.py diff --git a/.github/workflows/terraform-modules.yml b/.github/workflows/terraform-modules.yml index b7a9310..b0ddf30 100644 --- a/.github/workflows/terraform-modules.yml +++ b/.github/workflows/terraform-modules.yml @@ -85,4 +85,4 @@ jobs: Trigger: `${{ github.event_name }}` Reason: ${{ inputs.reason || 'Scheduled weekly refresh' }} - The generated module configuration, cards, and structured data are included in this pull request. + The generated module configuration, cards, structured data, and sitemap date are included in this pull request. diff --git a/README.md b/README.md index 9b4c22f..ae938d3 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,17 @@ Run the repository SEO audit locally: python3 scripts/seo-audit.py ``` +After publishing, check live redirect chains and final canonical destinations: + +```sh +python3 scripts/check-redirects.py +``` + +The separate `Live redirect checks` workflow checks production weekly and on +manual runs. The local SEO audit also checks internal canonical links and +fragments, distinct titles and descriptions, structured-data URLs, and sitemap +freshness for the generated Terraform catalogue. + The `Lighthouse and SEO` GitHub Actions workflow audits every canonical page on pull requests and pushes to `main`. It enforces minimum performance, accessibility, best-practices, and SEO scores together with lab thresholds for @@ -204,6 +215,6 @@ Largest Contentful Paint, cumulative layout shift, and total blocking time. It also validates HTML and checks internal fragments and external links. Google Search Console requires account-issued ownership verification. Follow -[`SEARCH_CONSOLE.md`](./SEARCH_CONSOLE.md) to add the URL-prefix property, -install the unmodified verification file, submit the sitemap, and request -indexing for each canonical page. +[`SEARCH_CONSOLE.md`](./SEARCH_CONSOLE.md) to verify a Domain property, retain +the unmodified verification file, submit the sitemap, and distinguish expected +redirect exclusions from actual redirect errors. diff --git a/SEARCH_CONSOLE.md b/SEARCH_CONSOLE.md index 28a61ac..474c89c 100644 --- a/SEARCH_CONSOLE.md +++ b/SEARCH_CONSOLE.md @@ -3,8 +3,9 @@ The repository is ready for Google Search Console: every indexable page has one self-referencing `https://native-cube.com/.../` canonical, explicit index/follow directives, matching Open Graph and structured-data URLs, and an entry in -`sitemap.xml`. `robots.txt` advertises that sitemap, while the duplicate -`/json-formatter/` alias remains excluded from indexing. +`sitemap.xml`. `robots.txt` advertises that sitemap. The duplicate +`/json-formatter/` alias points directly to `/yaml-formatter/` through an instant +meta refresh and a canonical link; it is excluded from the sitemap and navigation. Ownership verification must be completed by a Google account with access to Search Console. The verification value is account-issued and must not be @@ -35,7 +36,7 @@ invented or replaced with a placeholder. - `https://native-cube.com/visual-subnet-calculator/` - `https://native-cube.com/yaml-formatter/` - `https://native-cube.com/terraform-modules/` -4. Do not submit `/json-formatter/`; it is a `noindex` convenience alias. +4. Do not submit `/json-formatter/`; it is a permanent redirect alias. ## Confirm Google's selected canonical @@ -49,3 +50,88 @@ sitemap. The account owner can provide the downloaded verification file to a contributor for placement, but should not share Google credentials. + +## Redirect exclusions versus redirect failures + +Search Console's **Page with redirect** is expected for HTTP, `www`, the old +GitHub Pages hostname, paths missing their trailing slash, and `/json-formatter/`. +Google indexes the destination instead. Those source URLs should remain +excluded; repeatedly validating them as indexable pages will not fix anything. + +**Redirect error** is different: Google could not follow a chain because of a +loop, excessive redirects, an invalid or empty destination, or an overly long +URL. Copy the exact affected URL from the report and inspect every hop and the +final destination. **Alternate page with proper canonical tag** is also expected +for `/index.html` duplicates that GitHub Pages serves with HTTP 200. + +These distinctions are documented in Google's +[Page indexing report help](https://support.google.com/webmasters/answer/7440203). + +## Check the deployed site + +Run the dependency-free live audit after deployment: + +```sh +python3 scripts/check-redirects.py +``` + +It checks every sitemap page across HTTP/HTTPS, apex/`www`, and the old GitHub +Pages hostname, plus slashless paths, `index.html` duplicates, and formatter +aliases. It follows HTTP and instant meta-refresh redirects explicitly, rejects +loops and temporary or insecure redirects, and checks that each final page is +HTTP 200 with the expected canonical and no indexing restrictions. The separate +**Live redirect checks** workflow runs weekly and can be started manually in +Actions. It checks production, so run it after the source changes are published. + +An optional user agent helps investigate response differences: + +```sh +python3 scripts/check-redirects.py --user-agent Googlebot +``` + +Changing a user-agent string does not reproduce Google's crawler network or +replace Search Console's **Test live URL**. + +Public HTTP checks on 2 November 2026 confirmed that all eight canonical pages +returned 200 and the tested HTTP, `www`, and GitHub Pages variants redirected +permanently to the apex HTTPS URLs. The formatter alias still served the old +`noindex` directive before this change was deployed. This is a consolidation +signal issue; it does not prove the cause of an account's **Redirect error**. + +## Hosting settings and the formatter alias + +Keep **Settings → Pages → Custom domain** set to `native-cube.com` and +**Enforce HTTPS** enabled. The repository's `CNAME` file does not by itself +enforce HTTPS or configure DNS. Both the apex and `www` DNS records must point +to GitHub Pages for GitHub's automatic hostname redirect and HTTPS certificate +to work. See GitHub's +[custom-domain configuration](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site) +and [HTTPS settings](https://docs.github.com/en/pages/getting-started-with-github-pages/securing-your-github-pages-site-with-https). + +GitHub Pages serves static HTML and does not provide per-path HTTP redirect +rules in this repository. The formatter alias therefore uses an instant meta +refresh, which Google treats as a permanent redirect, plus a matching absolute +canonical and fallback link. JavaScript preserves query strings and fragments +for visitors. See Google's +[redirect guidance](https://developers.google.com/search/docs/crawling-indexing/301-redirects). +An HTTP 301 for this alias would require redirect support at a hosting or proxy +layer. Do not add redirect files for other hosting services and expect GitHub +Pages to apply them. + +Do not use `noindex` to consolidate the alias with its destination; rely on the +redirect and canonical together. Google's +[canonicalization guidance](https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls) +explains why `noindex` is unsuitable for canonical selection. + +After publishing, rerun the live audit, resubmit the canonical sitemap, and use +**Test live URL** for each affected destination. Request indexing for canonical +pages and validate actual **Redirect error** fixes. Historical exclusions remain +until Google recrawls them, and intentional redirects remain excluded. + +## Keep sitemap dates accurate + +Update a page's `lastmod` when its public content or metadata changes. The +Terraform renderer updates its sitemap date from the published catalogue's +`synced_at` value while preserving a later manual edit date. Include `sitemap.xml` +in catalogue update commits. The local SEO audit rejects a Terraform sitemap +date older than the catalogue. Do not reset every date simply because CI ran. diff --git a/argocd-applicationset-studio/index.html b/argocd-applicationset-studio/index.html index 481524f..a9eac89 100644 --- a/argocd-applicationset-studio/index.html +++ b/argocd-applicationset-studio/index.html @@ -153,7 +153,7 @@

Argo CD / Fleet engineering

-

Preview the fleet.
Ship with confidence.

+

Preview Argo CD ApplicationSets.
Review your fleet.

diff --git a/helm-chart-builder/index.html b/helm-chart-builder/index.html index 361e651..a6c9c7a 100644 --- a/helm-chart-builder/index.html +++ b/helm-chart-builder/index.html @@ -141,7 +141,7 @@

Helm / Chart authoring

-

Shape the values.
Generate the chart.

+

Build a Helm chart.
Download it in seconds.

diff --git a/json-formatter/index.html b/json-formatter/index.html index 926f8f4..d664059 100644 --- a/json-formatter/index.html +++ b/json-formatter/index.html @@ -3,15 +3,14 @@ - - + Redirecting to YAML & JSON Formatter | Native Cube