Skip to content

Commit eb90004

Browse files
committed
Add a script to publish to generate the publish commands
1 parent a349a60 commit eb90004

File tree

1 file changed

+198
-0
lines changed

1 file changed

+198
-0
lines changed

scripts/push-registry.py

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
#!/usr/bin/env python3
2+
3+
# Can be run without dependencies with
4+
#
5+
# uv run --with requests,pyyaml scripts/push-registry.py
6+
7+
import os
8+
import tempfile
9+
import requests
10+
import json
11+
import yaml
12+
import sys
13+
from logging import info, basicConfig, INFO
14+
15+
yaml_db_path = "themes/default/data/registry/packages"
16+
docs_path = "themes/default/content/registry/packages"
17+
tmpdir = tempfile.mkdtemp()
18+
19+
basicConfig(level=INFO)
20+
21+
info(f"Tempdir: {tmpdir}")
22+
23+
run_script = []
24+
25+
target = None
26+
if len(sys.argv) >= 2:
27+
target = sys.argv[1]
28+
29+
publishers = {
30+
"1Password": "1Password",
31+
"airbytehq": "airbytehq",
32+
"Aviatrix": "Aviatrix",
33+
"azaurus1": "azaurus1",
34+
"castai": "castai",
35+
"celest-dev": "celest-dev",
36+
"Checkly": "checkly",
37+
"Christian Nunciato": "christian_nunciato",
38+
"Chronosphere": "chronosphere",
39+
"Cisco": "cisco",
40+
"civo": "civo",
41+
"constellix": "constellix",
42+
"CrowdStrike": "crowdstrike",
43+
"CTFer.io": "ctfer",
44+
"Daniel Muehlbachler-Pietrzykowski": "daniel_muehlbachler_pietrzykowski",
45+
"DataRobot, Inc.": "datarobot",
46+
"Defang": "defang",
47+
"Descope": "descope",
48+
"dirien": "dirien",
49+
"dmacvicar": "dmacvicar",
50+
"Equinix": "equinix",
51+
"EventStore": "eventstore",
52+
"fivetran": "fivetran",
53+
"fortinetdev": "fortinetdev",
54+
"Genesiscloud": "genesiscloud",
55+
"goauthentik": "goauthentik",
56+
"Grapl Security": "grapl_security",
57+
"hashicorp": "hashicorp",
58+
"honeycombio": "honeycomb",
59+
"Ian Wahbe": "ian_wahbe",
60+
"Impart Security": "impart_security",
61+
"incident-io": "incident_io",
62+
"jfrog": "jfrog",
63+
"joneshf": "joneshf",
64+
"komminarlabs": "komminarlabs",
65+
"kong": "kong",
66+
"Koyeb": "koyeb",
67+
"labd": "labd",
68+
"lbrlabs": "lbrlabs",
69+
"Lee Zen": "lee_zen",
70+
"littlejo": "littlejo",
71+
"lucky3028": "lucky3028",
72+
"netlify": "netlify",
73+
"Nuage-Studio": "nuage_studio",
74+
"onelogin": "onelogin",
75+
"oun": "oun",
76+
"outscale": "outscale",
77+
"OVHcloud": "ovhcloud",
78+
"Paul Stack": "paul_stack",
79+
"pgEdge": "pgedge",
80+
"Piers Karsenbarg": "piers_karsenbarg",
81+
"pinecone-io": "pinecone",
82+
"planetscale": "planetscale",
83+
"port-labs": "port_labs",
84+
"prefecthq": "prefecthq",
85+
"Prodvana": "prodvana",
86+
"propelauth": "propelauth",
87+
"Pulumi": "pulumi",
88+
"pulumiverse - Marcel Arns": "pulumiverse",
89+
"pulumiverse": "pulumiverse",
90+
"Pulumiverse": "pulumiverse",
91+
"qdrant": "qdrant",
92+
"rancher": "rancher",
93+
"RedisLabs": "redislabs",
94+
"redpanda-data": "redpanda_data",
95+
"Rootly": "rootly",
96+
"Runpod": "runpod",
97+
"splightplatform": "splightplatform",
98+
"supabase": "supabase",
99+
"Symbiosis": "symbiosis",
100+
"temporalio": "temporalio",
101+
"terraform-lxd": "terraform_lxd",
102+
"Theo Gravity": "theo_gravity",
103+
"Three141": "three141",
104+
"Threefold": "threefold",
105+
"timescale": "timescale",
106+
"Twingate": "twingate",
107+
"UpCloudLtd": "upcloudltd",
108+
"Upstash": "upstash",
109+
"vantage-sh": "vantage-sh",
110+
"Vates": "vates",
111+
"Volcengine": "volcengine",
112+
"Wttech": "wttech",
113+
"zenduty": "zenduty",
114+
"Zscaler": "zscaler",
115+
}
116+
117+
for filename in os.listdir(yaml_db_path):
118+
if not filename.endswith('.yaml'):
119+
continue
120+
if target and target != filename.removesuffix(".yaml"):
121+
continue
122+
123+
filepath = os.path.join(yaml_db_path, filename)
124+
with open(filepath) as file:
125+
data = yaml.safe_load(file)
126+
127+
version = data.get('version')
128+
129+
schema_file_path = data.get('schema_file_path')
130+
schema_url = data.get(
131+
'schema_file_url',
132+
f"https://raw.githubusercontent.com/{data.get('repo_url').removeprefix("https://github.com/")}/refs/tags/{version}/{schema_file_path}",
133+
)
134+
135+
source = 'pulumi' if 'registry.opentofu.org' not in schema_url else "opentofu"
136+
name = data.get('name')
137+
publisher_display = data.get('publisher')
138+
139+
140+
if publisher_display == "DEPRECATED":
141+
continue
142+
elif publisher_display not in publishers:
143+
raise Exception(f"Missing publisher entry for {publisher_display}")
144+
publisher = publishers[publisher_display]
145+
146+
147+
package_version_name = f"{source}/{publisher}/{name}@{version}"
148+
info(f"Preparing command for {package_version_name}")
149+
150+
# We skip azure-native-v1, since it will (1) never be updated again and (2) isn't
151+
# actually a package, it's an alias to the azure native package.
152+
#
153+
# If azure-native-v2 ships (with azure-native now at v3), we will want to exclude
154+
# azure-native-v2 also.
155+
if name.startswith("azure-native") and name != "azure-native":
156+
continue
157+
158+
api_url = f"https://api.pulumi.com/api/registry/preview/packages/{source}/{publisher}/{name}/versions/{version}"
159+
existence_check = requests.head(api_url).status_code
160+
161+
if existence_check == 404:
162+
schema_file = os.path.join(tmpdir, name, "schema.json")
163+
os.makedirs(os.path.dirname(schema_file), exist_ok=True)
164+
165+
with open(schema_file, 'w') as sf:
166+
response = requests.get(schema_url)
167+
response.raise_for_status()
168+
169+
schema = None
170+
if (schema_file_path is not None and schema_file_path.endswith(".yaml")) or \
171+
(schema_url is not None and schema_url.endswith(".yaml")):
172+
schema = yaml.safe_load(response.content)
173+
else:
174+
schema = json.loads(response.content)
175+
176+
if "version" not in schema:
177+
schema["version"] = version.removeprefix("v")
178+
json.dump(schema, sf)
179+
180+
cmd = [
181+
"pulumi", "package", "publish", schema_file,
182+
f"--readme={docs_path}/{name}/_index.md",
183+
f"--source={source}",
184+
f"--publisher={publisher}",
185+
]
186+
187+
if os.path.isfile(os.path.join(docs_path, name, "_installation-configuration.md")):
188+
cmd.extend(["--installation-configuration", f"{docs_path}/{name}/installation-configuration.md"])
189+
190+
run_script.append(' '.join(cmd))
191+
elif existence_check == 200:
192+
info("Package already exists in the registry DB")
193+
else:
194+
info(f"Unable to check on package {package_version_name}")
195+
exit(1)
196+
197+
for cmd in run_script:
198+
print(cmd)

0 commit comments

Comments
 (0)