Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/scripts/build_payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
plus the package README, resolves the download URL from the GitHub
release's .zip asset, and writes two API content files:

* ``payload-create.json`` for POST /extensions (includes the ``id`` the
* ``payload-create.json`` for POST /extensions (includes the ``identifier`` the
API requires on create),
* ``payload-update.json`` for PUT /extensions/{id} (identical except the
``id``, which that endpoint rejects as an unknown field).
``identifier``, which that endpoint rejects as an unknown field).

The new release entry is keyed by the plain version (``"0.8.9"``), not the
git tag (``"branding-v0.8.9"``): the API sorts and compares releases
Expand Down Expand Up @@ -271,7 +271,7 @@ def main() -> None:
content["homepage_url"] = meta["homepage_url"]

create_content = dict(content)
create_content["id"] = ext_id
create_content["identifier"] = ext_id

size = len(json.dumps(create_content, ensure_ascii=False, separators=(",", ":")).encode("utf-8"))
if size > MAX_CONTENT_BYTES:
Expand Down
8 changes: 6 additions & 2 deletions .github/scripts/test_build_payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,19 @@ def build(self, history=None):

def test_preserves_manifest_metadata_and_compound_requirements(self):
create, update = self.build()
self.assertEqual(create["identifier"], self.meta["id"])
self.assertNotIn("id", create)
self.assertNotIn("identifier", update)
for field in self.meta:
self.assertEqual(create[field], self.meta[field])
if field != "id":
self.assertEqual(create[field], self.meta[field])
self.assertNotIn("website", create)
self.assertNotIn("homepage_url", create)
self.assertNotIn("id", update)
self.assertEqual(create["releases"][0]["requires"], self.meta["requires"])
self.assertNotIn("min_fossbilling_version", create["releases"][0])
self.assertEqual(create["readme"], "# Example\n")
self.assertEqual(create, {**update, "id": "example_module"})
self.assertEqual(create, {**update, "identifier": "example_module"})

def test_optional_homepage_and_icon(self):
self.meta["homepage_url"] = "https://example.com"
Expand Down
2 changes: 1 addition & 1 deletion .github/scripts/test_publish_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def test_build_uses_trusted_sibling_imports_despite_pythonpath(self):
result = subprocess.run(['bash', '-e', '-c', workflow_run('Build extension payload')], cwd=release, env=env, capture_output=True, text=True)
self.assertFalse((release / 'hostile-imported').exists(), 'Tagged module imported via PYTHONPATH')
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(json.loads((release / 'payload-create.json').read_text())['id'], 'branding')
self.assertEqual(json.loads((release / 'payload-create.json').read_text())['identifier'], 'branding')

def test_create_and_update_accept_the_merged_api_statuses(self):
for exists, method, code in [(False, "POST", 201), (True, "PUT", 202)]:
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,6 @@ The client authenticates with `client_credentials` and is bound to the
extensions v2 README, "Machine publishing"). If a publish fails with 409,
a revision is already pending review — a moderator resolves it in the
review queue, then re-run the workflow.

Directory creation sends the manifest’s public `id` as `identifier`. Developer
publisher bindings use the UUID `id` returned by the developer profile API.
Loading