Add a docs linter for unused partials and images (#64999)

* Add a docs linter for unused partials and images

Check whether any images in the `docs/img` directory or partials in the
`docs/pages/includes` directory are unused within the docs. This
prevents situations such as the following:

- An author unknowingly removes the only inclusion of a partial with
  important information, which should remain in the docs.
- An author introduces an image, thinking they might use it, but ends up
  using a different image, unnecessarily increasing repo size.
- An author forgets to remove unused assets, causing cluster that adds
  friction for other authors trying to navigate the `docs` directory.

Implementation details:
- Add a script to `build.assets` to list unused docs assets, including
  images and partials.
- Add a step to the `Lint (Docs)` workflow that checks whether the list
  is nonempty and, if so, exits with an error.

* Remove unused docs partials and images

* Refactor custom installer partials

The current approach injects a parameter into partial paths within
`custom-installer.mdx` in order to load one of several partials based on
the cloud provider and whether the installer is created statically or
dynamically.

However, if we use the automated approach in
`build.assets/unused-docs-assets.sh` to check for unused partials, it is
impossible to determine whether the partials we keep in
`docs/pages/includes` are included in the docs. This change refactors
the custom installer partials so we can use only static partial paths,
rather than dynamic ones.

* Apply suggestion from **hugoShaka**

Co-authored-by: Hugo Shaka <[email protected]>

---------

Co-authored-by: Hugo Shaka <[email protected]>
This commit is contained in:
Paul Gottschling
2026-05-22 19:50:07 +00:00
committed by GitHub
co-authored by Hugo Shaka
parent f5212798ec
commit 6cd0efe99b
34 changed files with 138 additions and 140 deletions
+10
View File
@@ -132,6 +132,16 @@ jobs:
working-directory: 'docs'
run: yarn spellcheck content/current
- name: Check for unused images and partials
working-directory: 'docs/content/current'
run: |
UNUSED=$(build.assets/unused-docs-assets.sh);
if [ -n "$UNUSED" ]; then
echo "There are unused docs partials and images:";
echo "$UNUSED";
exit 1;
fi
- name: Lint docs formatting
working-directory: 'docs'
run: yarn markdown-lint
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
set -euo pipefail
USED_IMG=$(mktemp /tmp/docs-img-used.XXXX);
ALL_IMG=$(mktemp /tmp/docs-img-all.XXXX);
USED_PARTIALS=$(mktemp /tmp/docs-partials-used.XXXX);
ALL_PARTIALS=$(mktemp /tmp/docs-partials-all.XXXX);
find docs/img -type f | sed "s|^docs/||" | sort > "$ALL_IMG";
find docs/pages/includes -type f | sort > "$ALL_PARTIALS";
grep -hERo "img/[A-Za-z0-9@\._\/-]+" docs/pages | sort >"$USED_IMG";
grep -hERo "docs/pages/includes/[A-Za-z0-9@\._\/-]+" docs/pages | sort >"$USED_PARTIALS";
UNUSED_IMG=$(comm -23 "$ALL_IMG" "$USED_IMG");
UNUSED_PARTIALS=$(comm -23 "$ALL_PARTIALS" "$USED_PARTIALS");
rm "$USED_IMG"
rm "$ALL_IMG"
rm "$USED_PARTIALS"
rm "$ALL_PARTIALS"
# Restore the "docs" path segment so a user can pipe this into rm or similar.
FULL_UNUSED_IMG=$(echo "$UNUSED_IMG" | sed -E "s|(img/[A-Za-z0-9@\._\/-]+)|docs/\1|");
# Exit with no error if there are only empty lines in the output.
printf "%s\n" $FULL_UNUSED_IMG $UNUSED_PARTIALS | grep -v "^$" || exit 0;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 486 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 411 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 578 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

@@ -4,7 +4,7 @@
### Use a custom installation script
(!docs/pages/includes/server-access/custom-installer.mdx matcher="aws"!)
(!docs/pages/includes/server-access/custom-installer-aws-config.mdx!)
### Use a custom SSM Document
@@ -4,7 +4,7 @@
### Use a custom installation script
(!docs/pages/includes/server-access/custom-installer.mdx matcher="azure"!)
(!docs/pages/includes/server-access/custom-installer-azure-config.mdx!)
If `client_id` is set in the Discovery Service config, custom installers will
also have the `{{ .AzureClientID }}` templating option.
@@ -4,4 +4,4 @@
### Use a custom installation script
(!docs/pages/includes/server-access/custom-installer.mdx matcher="gcp"!)
(!docs/pages/includes/server-access/custom-installer-gcp-config.mdx!)
@@ -1,19 +0,0 @@
You can download one of the following .pkg installers for macOS:
| Link | Binaries |
|-----------------------------------------------------------------------------------------------------------|--------------------------------------------|
| [`teleport-ent-(=cloud.version=).pkg`](https://cdn.teleport.dev/teleport-ent-(=cloud.version=).pkg) | `teleport`<br/>`tctl`<br/>`tsh`<br/>`tbot`<br/>`fdpass-teleport` |
You can also fetch an installer from the command line:
```code
$ curl -O https://cdn.teleport.dev/teleport-ent-(=cloud.version=).pkg
# Install on Macintosh HD
$ sudo installer -pkg teleport-ent-(=cloud.version=).pkg -target /
Password:
installer: Package name is teleport-ent-(=cloud.version=)
installer: Upgrading at base path /
installer: The upgrade was successful.
$ which teleport
/usr/local/bin/teleport
```
@@ -1,19 +0,0 @@
You can download one of the following .pkg installers for macOS:
| Link | Binaries |
|-----------------------------------------------------------------------------------------------------------|--------------------------------------------|
| [`teleport-ent-(=teleport.version=).pkg`](https://cdn.teleport.dev/teleport-ent-(=teleport.version=).pkg) | `teleport`<br/>`tctl`<br/>`tsh`<br/>`tbot`<br/>`fdpass-teleport`|
You can also fetch an installer from the command line:
```code
$ curl -O https://cdn.teleport.dev/teleport-ent-(=teleport.version=).pkg
# Install on Macintosh HD
$ sudo installer -pkg teleport-ent-(=teleport.version=).pkg -target /
Password:
installer: Package name is teleport-ent-(=teleport.version=)
installer: Upgrading at base path /
installer: The upgrade was successful.
$ which teleport
/usr/local/bin/teleport
```
@@ -1,32 +0,0 @@
{{ forwarder="fluentd.fluentd.svc.cluster.local" }}
The plugin generates several setup files:
| File(s) | Purpose |
|------------------------------------|---------------------------------------------------------------------|
| `ca.crt` and `ca.key` | Self-signed CA certificate and private key for Fluentd |
| `server.crt` and `server.key` | Fluentd server certificate and key |
| `client.crt` and `client.key` | Fluentd client certificate and key, all signed by the generated CA |
| `teleport-plugin-event-handler-values.yaml` | Example event handler helm configuration |
| `fluent.conf` | Fluentd plugin configuration |
<details>
<summary>Running the Event Handler separately from the log forwarder</summary>
This guide assumes that you are running the Event Handler on the same host or
Kubernetes pod as your log forwarder. If you are not, you will need to instruct
the Event Handler to generate mTLS certificates for subjects besides
`localhost`. To do this, use the `--dns-names` flag of the
`teleport-event-handler` configure command.
For example, if your log forwarder is addressable at `{{ forwarder }}`,
you would run the following `configure` command:
```code
$ teleport-event-handler configure --dns-names={{ forwarder }}
```
The `--dns-names` flag accepts a comma-separated list of DNS names. It will
append subject alternative names (SANs) to the server certificate (the one you
will provide to your log forwarder) for each DNS name in the list.
</details>
@@ -0,0 +1,21 @@
(!docs/pages/includes/server-access/custom-installer-editing.mdx!)
Multiple `installer` resources can exist and be specified in the
`aws.install.script_name` section:
<Tabs>
<TabItem label="Dynamic configuration (recommended)">
Edit the Discovery Config to specify a custom installer script:
```yaml
(!docs/pages/includes/server-access/custom-installer-aws-dynamic.yaml!)
```
</TabItem>
<TabItem label="Static configuration">
Edit the `teleport.yaml` configuration to specify a custom installer script:
```yaml
(!docs/pages/includes/server-access/custom-installer-aws.yaml!)
```
</TabItem>
</Tabs>
(!docs/pages/includes/server-access/custom-installer-reference.mdx!)
@@ -0,0 +1,21 @@
(!docs/pages/includes/server-access/custom-installer-editing.mdx!)
Multiple `installer` resources can exist and be specified in the
`azure.install.script_name` section:
<Tabs>
<TabItem label="Dynamic configuration (recommended)">
Edit the Discovery Config to specify a custom installer script:
```yaml
(!docs/pages/includes/server-access/custom-installer-azure-dynamic.yaml!)
```
</TabItem>
<TabItem label="Static configuration">
Edit the `teleport.yaml` configuration to specify a custom installer script:
```yaml
(!docs/pages/includes/server-access/custom-installer-azure.yaml!)
```
</TabItem>
</Tabs>
(!docs/pages/includes/server-access/custom-installer-reference.mdx!)
@@ -0,0 +1,35 @@
To customize an installer, your user must have a role that allows `list`, `create`, `read` and `update` verbs on the `installer` resource.
Create a file called `installer-manager.yaml` with the following content:
```yaml
kind: role
version: v5
metadata:
name: installer-manager
spec:
allow:
rules:
- resources: [installer]
verbs: [list, create, read, update]
```
Create the role:
```code
$ tctl create -f installer-manager.yaml
# role 'installer-manager' has been created
```
(!docs/pages/includes/create-role-using-web.mdx!)
The preset `editor` role has the required permissions by default.
To customize the default installer script, execute the following command on
your workstation:
```code
$ tctl edit installer/default-installer
```
After making the desired changes to the default installer, save and close the
file in your text editor.
@@ -0,0 +1,21 @@
(!docs/pages/includes/server-access/custom-installer-editing.mdx!)
Multiple `installer` resources can exist and be specified in the
`gcp.install.script_name` section:
<Tabs>
<TabItem label="Dynamic configuration (recommended)">
Edit the Discovery Config to specify a custom installer script:
```yaml
(!docs/pages/includes/server-access/custom-installer-gcp-dynamic.yaml!)
```
</TabItem>
<TabItem label="Static configuration">
Edit the `teleport.yaml` configuration to specify a custom installer script:
```yaml
(!docs/pages/includes/server-access/custom-installer-gcp.yaml!)
```
</TabItem>
</Tabs>
(!docs/pages/includes/server-access/custom-installer-reference.mdx!)
@@ -1,60 +1,3 @@
{{ matcher="bar" }}
To customize an installer, your user must have a role that allows `list`, `create`, `read` and `update` verbs on the `installer` resource.
Create a file called `installer-manager.yaml` with the following content:
```yaml
kind: role
version: v5
metadata:
name: installer-manager
spec:
allow:
rules:
- resources: [installer]
verbs: [list, create, read, update]
```
Create the role:
```code
$ tctl create -f installer-manager.yaml
# role 'installer-manager' has been created
```
(!docs/pages/includes/create-role-using-web.mdx!)
The preset `editor` role has the required permissions by default.
To customize the default installer script, execute the following command on
your workstation:
```code
$ tctl edit installer/default-installer
```
After making the desired changes to the default installer, save and close the
file in your text editor.
Multiple `installer` resources can exist and be specified in the
`{{ matcher }}.install.script_name` section:
<Tabs>
<TabItem label="Dynamic configuration (recommended)">
Edit the Discovery Config to specify a custom installer script:
```yaml
(!docs/pages/includes/server-access/custom-installer-{{ matcher }}-dynamic.yaml!)
```
</TabItem>
<TabItem label="Static configuration">
Edit the `teleport.yaml` configuration to specify a custom installer script:
```yaml
(!docs/pages/includes/server-access/custom-installer-{{ matcher }}.yaml!)
```
</TabItem>
</Tabs>
---
The `installer` resource has the following templating options:
- `{{ .MajorVersion }}`: the major version of Teleport to use when
-10
View File
@@ -1,10 +0,0 @@
<details>
<summary>SAML Single Logout</summary>
Setting the `spec.single_logout_url` endpoint in SAML connectors enables SAML SLO (Single Logout).
If enabled, upon logging out of Teleport, users will also be logged out of the SAML provider session, which
may also log them out of any other non-Teleport applications which they are currently logged into using the same SAML provider.
For optimal user experience, we recommend keeping this disabled unless necessary.
Refer to your SAML provider's documentation for instructions on where to obtain this URL.
</details>