From 4080632ee05fc3d7734c856b3af3a024d63197ef Mon Sep 17 00:00:00 2001
From: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Date: Mon, 26 Feb 2024 18:23:37 +0100
Subject: [PATCH] [prdoc] Validate crate names (#3467)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Changes:
- Add CI script to check that the `crate` names that are mentioned in
prdocs are valid.

We can extend it lateron to also validate the correct SemVer bumps as
introduced in https://github.com/paritytech/polkadot-sdk/pull/3441.

Example output:
```pre
$ python3 .github/scripts/check-prdoc.py Cargo.toml prdoc/*.prdoc

🔎 Reading workspace polkadot-sdk/Cargo.toml.
📦 Checking 36 prdocs against 494 crates.
✅ All prdocs are valid.
```

Note that not all old prdocs pass the check since crates have been
renamed:
```pre
$ python3 .github/scripts/check-prdoc.py Cargo.toml prdoc/**/*.prdoc

🔎 Reading workspace polkadot-sdk/Cargo.toml.
📦 Checking 186 prdocs against 494 crates.
❌ Some prdocs are invalid.
💥 prdoc/1.4.0/pr_1926.prdoc lists invalid crate: node-cli
💥 prdoc/1.4.0/pr_2086.prdoc lists invalid crate: xcm-executor
💥 prdoc/1.4.0/pr_2107.prdoc lists invalid crate: xcm
💥 prdoc/1.6.0/pr_2684.prdoc lists invalid crate: xcm-builder

```

---------

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
---
 .github/scripts/check-prdoc.py    | 71 +++++++++++++++++++++++++++++++
 .github/workflows/check-prdoc.yml |  8 ++++
 prdoc/1.4.0/pr_1246.prdoc         |  2 +-
 prdoc/1.6.0/pr_2689.prdoc         |  2 +-
 prdoc/1.6.0/pr_2771.prdoc         |  2 +-
 prdoc/pr_3412.prdoc               |  2 +-
 6 files changed, 83 insertions(+), 4 deletions(-)
 create mode 100644 .github/scripts/check-prdoc.py

diff --git a/.github/scripts/check-prdoc.py b/.github/scripts/check-prdoc.py
new file mode 100644
index 00000000000..42b063f2885
--- /dev/null
+++ b/.github/scripts/check-prdoc.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+
+'''
+Ensure that the prdoc files are valid.
+
+# Example
+
+```sh
+python3 -m pip install cargo-workspace
+python3 .github/scripts/check-prdoc.py Cargo.toml prdoc/*.prdoc
+```
+
+Produces example output:
+```pre
+🔎 Reading workspace polkadot-sdk/Cargo.toml
+📦 Checking 32 prdocs against 493 crates.
+✅ All prdocs are valid
+```
+'''
+
+import os
+import yaml
+import argparse
+import cargo_workspace
+
+def check_prdoc_crate_names(root, paths):
+	'''
+	Check that all crates of the `crates` section of each prdoc is present in the workspace.
+	'''
+	
+	print(f'🔎 Reading workspace {root}.')
+	workspace = cargo_workspace.Workspace.from_path(root)
+	crate_names = [crate.name for crate in workspace.crates]
+
+	print(f'📦 Checking {len(paths)} prdocs against {len(crate_names)} crates.')
+	faulty = {}
+
+	for path in paths:
+		with open(path, 'r') as f:
+			prdoc = yaml.safe_load(f)
+
+		for crate in prdoc.get('crates', []):
+			crate = crate['name']
+			if crate in crate_names:
+				continue
+
+			faulty.setdefault(path, []).append(crate)
+
+	if len(faulty) == 0:
+		print('✅ All prdocs are valid.')
+	else:
+		print('❌ Some prdocs are invalid.')
+		for path, crates in faulty.items():
+			print(f'💥 {path} lists invalid crate: {", ".join(crates)}')
+		exit(1)
+
+def parse_args():
+	parser = argparse.ArgumentParser(description='Check prdoc files')
+	parser.add_argument('root', help='The cargo workspace manifest', metavar='root', type=str, nargs=1)
+	parser.add_argument('prdoc', help='The prdoc files', metavar='prdoc', type=str, nargs='*')
+	args = parser.parse_args()
+
+	if len(args.prdoc) == 0:
+		print('❌ Need at least one prdoc file as argument.')
+		exit(1)
+
+	return { 'root': os.path.abspath(args.root[0]), 'prdocs': args.prdoc }
+
+if __name__ == '__main__':
+	args = parse_args()
+	check_prdoc_crate_names(args['root'], args['prdocs'])
diff --git a/.github/workflows/check-prdoc.yml b/.github/workflows/check-prdoc.yml
index 91701ca036e..c31dee06ec5 100644
--- a/.github/workflows/check-prdoc.yml
+++ b/.github/workflows/check-prdoc.yml
@@ -57,3 +57,11 @@ jobs:
           echo "Checking for PR#${GITHUB_PR}"
           echo "You can find more information about PRDoc at $PRDOC_DOC"
           $ENGINE run --rm -v $PWD:/repo -e RUST_LOG=info $IMAGE check -n ${GITHUB_PR}
+
+      - name: Validate prdoc for PR#${{ github.event.pull_request.number }}
+        if: ${{ !contains(steps.get-labels.outputs.labels, 'R0') }}
+        run: |
+          echo "Validating PR#${GITHUB_PR}"
+          python3 --version
+          python3 -m pip install cargo-workspace==1.2.1
+          python3 .github/scripts/check-prdoc.py Cargo.toml prdoc/pr_${GITHUB_PR}.prdoc
diff --git a/prdoc/1.4.0/pr_1246.prdoc b/prdoc/1.4.0/pr_1246.prdoc
index a4d270c45cb..3b5c2017f22 100644
--- a/prdoc/1.4.0/pr_1246.prdoc
+++ b/prdoc/1.4.0/pr_1246.prdoc
@@ -11,7 +11,7 @@ migrations:
       description: "Messages from the DMP dispatch queue will be moved over to the MQ pallet via `on_initialize`. This happens over multiple blocks and emits a `Completed` event at the end. The pallet can be un-deployed and deleted afterwards. Note that the migration reverses the order of messages, which should be acceptable as a one-off."
 
 crates:
-  - name: cumulus_pallet_xcmp_queue
+  - name: cumulus-pallet-xcmp-queue
     note: Pallet config must be altered according to the MR description.
 
 host_functions: []
diff --git a/prdoc/1.6.0/pr_2689.prdoc b/prdoc/1.6.0/pr_2689.prdoc
index 847c3e8026c..5d3081e3a4c 100644
--- a/prdoc/1.6.0/pr_2689.prdoc
+++ b/prdoc/1.6.0/pr_2689.prdoc
@@ -1,7 +1,7 @@
 # Schema: Parity PR Documentation Schema (prdoc)
 # See doc at https://github.com/paritytech/prdoc
 
-title: BEEFY: Support compatibility with Warp Sync - Allow Warp Sync for Validators
+title: "BEEFY: Support compatibility with Warp Sync - Allow Warp Sync for Validators"
 
 doc:
   - audience: Node Operator
diff --git a/prdoc/1.6.0/pr_2771.prdoc b/prdoc/1.6.0/pr_2771.prdoc
index 1b49162e439..50fb99556ec 100644
--- a/prdoc/1.6.0/pr_2771.prdoc
+++ b/prdoc/1.6.0/pr_2771.prdoc
@@ -6,4 +6,4 @@ doc:
       Enable better req-response protocol versioning, by allowing for fallback requests on different protocols.
 
 crates:
-  - name: sc_network
+  - name: sc-network
diff --git a/prdoc/pr_3412.prdoc b/prdoc/pr_3412.prdoc
index d68f05e45dc..1ee6edfeb83 100644
--- a/prdoc/pr_3412.prdoc
+++ b/prdoc/pr_3412.prdoc
@@ -13,5 +13,5 @@ doc:
 
 crates:
   - name: pallet-babe
-  - name: pallet-aura-ext
+  - name: cumulus-pallet-aura-ext
   - name: pallet-session
-- 
GitLab