Repository navigation
Confluence plugin: limitations left open by the atlassian-python-api 5.x migration #242
Description
Follow-up to #214. The 5.x migration left four things unresolved. None of them
block the migration — they were deliberately kept out of it to keep that change
scoped to the dependency — but each is a real gap.
1. create_file can only create the incident home page
dispatch.storage.flows.create_storage calls create_file three times: once
with the project storage root, then twice more with the page id it just got
back, for "Logs" and "Screengrabs". dispatch.document.flows.create_document
calls it a fourth time with subject.storage.resource_id for the blank-document
path.
The Confluence plugin uses that argument as a space key, which is correct
only for the first call. The other three now fail cleanly — logged error, falsy
return, which callers check — but they cannot succeed:
- Cloud:
get_space_by_key("900001")→ValueError: No space found with key - Server:
space={"key": "900001"}→ 400
This predates the 5.x migration
The parameter has been named drive_id since the plugin was contributed
(ead6707, #2940). Two separate core changes bracket it:
- #2273 (case management) introduced
create_file(parent_id=...)for the
first call — before the plugin existed. So the gating call was already
broken on the day the plugin landed:TypeError: unexpected keyword argument 'parent_id', caught by the caller'sexcept, logged, and returned. - #4908 (alternative folder structure) later converted the Logs and
Screengrabs calls from positional toparent_id=, and addedfolder_one
andstorage_use_folder_one_as_primary.
At contribution, then, exactly one of the three calls was broken — and it was
the one everything else depends on, since create_storage is the only writer
of subject.storage, which create_document, copy_file and
report/flows.py all dereference. Only a lint pass and a typing modernization
touched the signature in between; neither renamed it.
Pairing Confluence with a different storage backend does not rescue this:
create_document copies the template with the storage plugin, not the
document plugin, so running Google Drive for storage would hand Confluence's
update() a Drive file id.
So the plugin created zero pages before #243 and creates one now. The
space-key-versus-page-id mismatch is original; what is new is that the first
call now gets far enough to expose it.
Worth noting that someone clearly did run this against a real Confluence — the
move_file_confluence workaround in section 2 and its "find and fix why the
page is not created under the parent_id" TODO are observations of live API
behaviour. That is consistent with the functions being exercised individually
rather than through incident_create_flow: copy_file's signature does match
its caller, and create_file works when called positionally.
Confluence has no folders, so making these work means deciding what the
sub-folder concept maps to — child pages under the incident home page is the
obvious answer — and giving the storage plugin interface a way to say so.
Currently pinned by test_create_file_cannot_make_sub_pages_from_a_page_id so
the limitation is documented rather than implied.
2. move_file_confluence is still a hardcoded Cloud v1 call
plugin.py builds {api_url}wiki/rest/api/content/{id}/move/append/{parent}
with requests directly, bypassing the client. On Server there is no /wiki
context path, so it 404s; on Cloud it targets a v1 content endpoint Atlassian
removed on 2025-04-30. requests does not raise on 4xx and the response is
discarded, so it fails silently on both.
copy_file already passes parent_id to create_page, which files the page
under the right parent, so this call appears to be redundant — its own TODO
says as much. It should either be deleted or reimplemented against an endpoint
that exists.
3. A Cloud site on a non-atlassian.net hostname gets no /wiki prefix
ConfluenceBase.__init__ appends the /wiki context path only for hostnames
ending in .atlassian.net / .jira.com, or the API gateway. 4.0.7 had the same
heuristic, so this is inherited rather than introduced, and the weblink half is
now fixed — configuring api_url as https://site/wiki works as a workaround
and no longer doubles the path. Worth deciding whether to normalize the
configured URL ourselves rather than depend on upstream's hostname sniffing.
4. Nothing has been verified against a live Confluence
The migration was verified against Atlassian's published v2 OpenAPI spec and the
installed 5.0.3 source, and the test fake validates request payloads against
that schema. That is enough to catch a missing required field — it caught
status on PageUpdateRequest during review — but it cannot prove the API
accepts what we send.
One manual create + update against a real Cloud site, and the same against a
Server instance, would close this. It would also settle a loose end from #243:
copy_file used to put a whole body object where the API's
body.storage.value takes a string, and while that payload is objectively
malformed, "Confluence answers 400" is an inference from the schema that nobody
has executed against a live instance. The live-provider suites for Slack, Zoom and
Teams are the existing pattern for making this repeatable
(DISPATCH_*_TEST_* env vars, skipped when unset).
Activity