Skip to content

Commit aa988a6

Browse files
committed
Push to the live registry after publishing
1 parent eb90004 commit aa988a6

File tree

3 files changed

+172
-61
lines changed

3 files changed

+172
-61
lines changed

.github/workflows/pull-request.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ jobs:
1919
- lint-markdown
2020
- lint-scripts
2121
- preview
22+
- test-live-publish
2223
runs-on: ubuntu-latest
2324
steps:
2425
- uses: guibranco/github-status-action-v2@0849440ec82c5fa69b2377725b9b7852a3977e76 # v1.1.13
@@ -77,6 +78,18 @@ jobs:
7778
- name: Run Linter
7879
run: yarn run lint
7980

81+
test-live-publish:
82+
name: Test Live Registry Publish
83+
runs-on: ubuntu-latest
84+
steps:
85+
- name: Check out branch
86+
uses: actions/checkout@v4
87+
- name: Install uv
88+
uses: astral-sh/setup-uv@v5
89+
- run: uv run --with requests,pyyaml scripts/ci/push-registry.py --dry-run
90+
env:
91+
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
92+
8093
# Preview runs a registry build into a commit specific S3 bucket to preview changes.
8194
#
8295
# A link to the generated build is appended to the PR on each commit.

.github/workflows/push.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ jobs:
6464
with:
6565
name: origin-bucket-metadata
6666
path: origin-bucket-metadata.json
67+
- name: Install uv
68+
uses: astral-sh/setup-uv@v5
69+
- name: Push to the Live Registry
70+
run: uv run --with requests,pyyaml ./scripts/ci/push-registry.py
71+
env:
72+
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
6773

6874
notify:
6975
if: failure()

scripts/push-registry.py renamed to scripts/ci/push-registry.py

Lines changed: 153 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,122 +2,198 @@
22

33
# Can be run without dependencies with
44
#
5-
# uv run --with requests,pyyaml scripts/push-registry.py
5+
# uv run --with requests,pyyaml scripts/ci/push-registry.py
66

77
import os
88
import tempfile
99
import requests
10+
import subprocess
1011
import json
1112
import yaml
12-
import sys
13-
from logging import info, basicConfig, INFO
13+
import argparse
14+
from logging import info, warning, basicConfig, WARNING
15+
16+
basicConfig(level=WARNING)
1417

1518
yaml_db_path = "themes/default/data/registry/packages"
1619
docs_path = "themes/default/content/registry/packages"
1720
tmpdir = tempfile.mkdtemp()
1821

19-
basicConfig(level=INFO)
22+
token = os.getenv("PULUMI_ACCESS_TOKEN")
2023

21-
info(f"Tempdir: {tmpdir}")
24+
parser = argparse.ArgumentParser(
25+
prog='push-registry',
26+
description='Push the contents of the pulumi/registry GitHub repo to the live registry service',
27+
epilog='This is a Pulumi internal tool - it is not intended for external use')
28+
parser.add_argument("--target", default=None, help='Only focus on one provider. This should just be the name, like "aws"')
29+
parser.add_argument("--dry-run", action='store_true', help="Don't actually publish provider, but do everything else")
2230

23-
run_script = []
31+
args = parser.parse_args()
2432

25-
target = None
26-
if len(sys.argv) >= 2:
27-
target = sys.argv[1]
33+
info(f"Tempdir: {tmpdir}")
2834

2935
publishers = {
3036
"1Password": "1Password",
31-
"airbytehq": "airbytehq",
3237
"Aviatrix": "Aviatrix",
33-
"azaurus1": "azaurus1",
34-
"castai": "castai",
35-
"celest-dev": "celest-dev",
38+
"CTFer.io": "ctfer",
3639
"Checkly": "checkly",
3740
"Christian Nunciato": "christian_nunciato",
3841
"Chronosphere": "chronosphere",
3942
"Cisco": "cisco",
40-
"civo": "civo",
41-
"constellix": "constellix",
4243
"CrowdStrike": "crowdstrike",
43-
"CTFer.io": "ctfer",
4444
"Daniel Muehlbachler-Pietrzykowski": "daniel_muehlbachler_pietrzykowski",
4545
"DataRobot, Inc.": "datarobot",
4646
"Defang": "defang",
4747
"Descope": "descope",
48-
"dirien": "dirien",
49-
"dmacvicar": "dmacvicar",
5048
"Equinix": "equinix",
5149
"EventStore": "eventstore",
50+
"Genesiscloud": "genesiscloud",
51+
"Grapl Security": "grapl_security",
52+
"Ian Wahbe": "ian_wahbe",
53+
"Impart Security": "impart_security",
54+
"Koyeb": "koyeb",
55+
"Lee Zen": "lee_zen",
56+
"Nuage-Studio": "nuage_studio",
57+
"OVHcloud": "ovhcloud",
58+
"Paul Stack": "paul_stack",
59+
"Piers Karsenbarg": "piers_karsenbarg",
60+
"Prodvana": "prodvana",
61+
"Pulumi": "pulumi",
62+
"Pulumiverse": "pulumiverse",
63+
"RedisLabs": "redislabs",
64+
"Rootly": "rootly",
65+
"Runpod": "runpod",
66+
"Symbiosis": "symbiosis",
67+
"Theo Gravity": "theo_gravity",
68+
"Three141": "three141",
69+
"Threefold": "threefold",
70+
"Twingate": "twingate",
71+
"UpCloudLtd": "upcloudltd",
72+
"Upstash": "upstash",
73+
"Vates": "vates",
74+
"Volcengine": "volcengine",
75+
"Wttech": "wttech",
76+
"Zscaler": "zscaler",
77+
"airbytehq": "airbytehq",
78+
"akeyless-community": "akeyless-community",
79+
"aptible": "aptible",
80+
"athenz": "athenz",
81+
"azaurus1": "azaurus1",
82+
"castai": "castai",
83+
"celest-dev": "celest-dev",
84+
"chainguard-dev": "chainguard-dev",
85+
"checkpointsw": "checkpointsw",
86+
"ciscodevnet": "ciscodevnet",
87+
"ciscodevnet": "ciscodevnet",
88+
"civo": "civo",
89+
"cloudfoundry-community": "cloudfoundry-community",
90+
"coder": "coder",
91+
"constellix": "constellix",
92+
"coralogix": "coralogix",
93+
"cox-automotive": "cox-automotive",
94+
"cyralinc": "cyralinc",
95+
"datadrivers": "datadrivers",
96+
"dell": "dell",
97+
"dell": "dell",
98+
"dell": "dell",
99+
"denouche": "denouche",
100+
"dirien": "dirien",
101+
"dmacvicar": "dmacvicar",
102+
"dome9": "dome9",
103+
"drfaust92": "drfaust92",
104+
"e-breuninger": "e-breuninger",
105+
"edge-center": "edge-center",
106+
"elastic": "elastic",
107+
"elastic-infra": "elastic-infra",
108+
"ferlab-ste-justine": "ferlab-ste-justine",
109+
"ferlab-ste-justine": "ferlab-ste-justine",
52110
"fivetran": "fivetran",
111+
"flexibleenginecloud": "flexibleenginecloud",
53112
"fortinetdev": "fortinetdev",
54-
"Genesiscloud": "genesiscloud",
113+
"g-core": "g-core",
114+
"glesys": "glesys",
55115
"goauthentik": "goauthentik",
56-
"Grapl Security": "grapl_security",
57116
"hashicorp": "hashicorp",
58117
"honeycombio": "honeycomb",
59-
"Ian Wahbe": "ian_wahbe",
60-
"Impart Security": "impart_security",
118+
"hpe": "hpe",
119+
"ibm-cloud": "ibm-cloud",
120+
"imperva": "imperva",
61121
"incident-io": "incident_io",
122+
"infobloxopen": "infobloxopen",
123+
"ionos-cloud": "ionos-cloud",
124+
"iterative": "iterative",
125+
"jdamata": "jdamata",
62126
"jfrog": "jfrog",
63127
"joneshf": "joneshf",
128+
"juju": "juju",
129+
"k-yomo": "k-yomo",
64130
"komminarlabs": "komminarlabs",
65131
"kong": "kong",
66-
"Koyeb": "koyeb",
67132
"labd": "labd",
133+
"lacework": "lacework",
68134
"lbrlabs": "lbrlabs",
69-
"Lee Zen": "lee_zen",
70135
"littlejo": "littlejo",
136+
"logdna": "logdna",
137+
"logzio": "logzio",
71138
"lucky3028": "lucky3028",
139+
"mastercard": "mastercard",
140+
"maxlaverse": "maxlaverse",
141+
"megaport": "megaport",
142+
"mrolla": "mrolla",
143+
"nats-io": "nats-io",
144+
"netapp": "netapp",
72145
"netlify": "netlify",
73-
"Nuage-Studio": "nuage_studio",
146+
"octopusdeploylabs": "octopusdeploylabs",
74147
"onelogin": "onelogin",
148+
"opennebula": "opennebula",
149+
"opensearch-project": "opensearch-project",
150+
"opentelekomcloud": "opentelekomcloud",
75151
"oun": "oun",
76152
"outscale": "outscale",
77-
"OVHcloud": "ovhcloud",
78-
"Paul Stack": "paul_stack",
153+
"paloaltonetworks": "paloaltonetworks",
154+
"paloaltonetworks": "paloaltonetworks",
155+
"pan-net": "pan-net",
156+
"paultyng": "paultyng",
79157
"pgEdge": "pgedge",
80-
"Piers Karsenbarg": "piers_karsenbarg",
158+
"philips-software": "philips-software",
81159
"pinecone-io": "pinecone",
82160
"planetscale": "planetscale",
83161
"port-labs": "port_labs",
84162
"prefecthq": "prefecthq",
85-
"Prodvana": "prodvana",
86163
"propelauth": "propelauth",
87-
"Pulumi": "pulumi",
88164
"pulumiverse - Marcel Arns": "pulumiverse",
89165
"pulumiverse": "pulumiverse",
90-
"Pulumiverse": "pulumiverse",
91166
"qdrant": "qdrant",
92167
"rancher": "rancher",
93-
"RedisLabs": "redislabs",
94168
"redpanda-data": "redpanda_data",
95-
"Rootly": "rootly",
96-
"Runpod": "runpod",
169+
"rollbar": "rollbar",
170+
"selectel": "selectel",
171+
"spectrocloud": "spectrocloud",
97172
"splightplatform": "splightplatform",
98173
"supabase": "supabase",
99-
"Symbiosis": "symbiosis",
174+
"sysdiglabs": "sysdiglabs",
100175
"temporalio": "temporalio",
176+
"tencentcloudstack": "tencentcloudstack",
101177
"terraform-lxd": "terraform_lxd",
102-
"Theo Gravity": "theo_gravity",
103-
"Three141": "three141",
104-
"Threefold": "threefold",
178+
"terraform-routeros": "terraform-routeros",
105179
"timescale": "timescale",
106-
"Twingate": "twingate",
107-
"UpCloudLtd": "upcloudltd",
108-
"Upstash": "upstash",
180+
"ucloud": "ucloud",
109181
"vantage-sh": "vantage-sh",
110-
"Vates": "vates",
111-
"Volcengine": "volcengine",
112-
"Wttech": "wttech",
182+
"vk-cs": "vk-cs",
183+
"vmware": "vmware",
184+
"vmware": "vmware",
185+
"vmware": "vmware",
186+
"vmware": "vmware",
187+
"vmware": "vmware",
113188
"zenduty": "zenduty",
114-
"Zscaler": "zscaler",
115189
}
116190

191+
has_failed = False
192+
117193
for filename in os.listdir(yaml_db_path):
118194
if not filename.endswith('.yaml'):
119195
continue
120-
if target and target != filename.removesuffix(".yaml"):
196+
if args.target and args.target != filename.removesuffix(".yaml"):
121197
continue
122198

123199
filepath = os.path.join(yaml_db_path, filename)
@@ -140,11 +216,11 @@
140216
if publisher_display == "DEPRECATED":
141217
continue
142218
elif publisher_display not in publishers:
143-
raise Exception(f"Missing publisher entry for {publisher_display}")
219+
raise Exception(f'Missing publisher entry for "{publisher_display}"')
144220
publisher = publishers[publisher_display]
145221

146222

147-
package_version_name = f"{source}/{publisher}/{name}@{version}"
223+
package_version_name = f"{source}/{publisher}/{name}@{version.removeprefix("v")}"
148224
info(f"Preparing command for {package_version_name}")
149225

150226
# We skip azure-native-v1, since it will (1) never be updated again and (2) isn't
@@ -155,8 +231,11 @@
155231
if name.startswith("azure-native") and name != "azure-native":
156232
continue
157233

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
234+
235+
api_url = f"https://api.pulumi.com/api/preview/registry/packages/{source}/{publisher}/{name}/versions/{version.removeprefix("v")}"
236+
existence_check = requests.get(api_url, headers={
237+
"Authorization": f"token {token}",
238+
}).status_code
160239

161240
if existence_check == 404:
162241
schema_file = os.path.join(tmpdir, name, "schema.json")
@@ -173,26 +252,39 @@
173252
else:
174253
schema = json.loads(response.content)
175254

176-
if "version" not in schema:
255+
256+
if "version" not in schema or schema["version"] != version.removeprefix("v"):
177257
schema["version"] = version.removeprefix("v")
178-
json.dump(schema, sf)
258+
json.dump(schema, sf)
259+
179260

180261
cmd = [
181-
"pulumi", "package", "publish", schema_file,
182-
f"--readme={docs_path}/{name}/_index.md",
183-
f"--source={source}",
184-
f"--publisher={publisher}",
262+
"pulumi", "package", "publish",
263+
schema_file,
264+
"--readme", f"{docs_path}/{name}/_index.md",
265+
"--source", source,
266+
"--publisher", publisher,
185267
]
186268

187269
if os.path.isfile(os.path.join(docs_path, name, "_installation-configuration.md")):
188270
cmd.extend(["--installation-configuration", f"{docs_path}/{name}/installation-configuration.md"])
189271

190-
run_script.append(' '.join(cmd))
272+
if args.dry_run:
273+
print(" ".join(cmd))
274+
else:
275+
try:
276+
subprocess.run(cmd, shell=False)
277+
except subprocess.CalledProcessError:
278+
warning(f"Failed to run {" ".join(cmd)}")
279+
has_failed=True
280+
281+
os.remove(schema_file)
282+
os.removedirs(os.path.dirname(schema_file))
191283
elif existence_check == 200:
192284
info("Package already exists in the registry DB")
193285
else:
194-
info(f"Unable to check on package {package_version_name}")
195-
exit(1)
286+
warning(f"Unable to check on package {package_version_name}")
287+
has_failed=True
196288

197-
for cmd in run_script:
198-
print(cmd)
289+
if has_failed:
290+
exit(1)

0 commit comments

Comments
 (0)