Add mirror-publish command to publish an existing Dataverse draft - #41
Merged
Merged
Conversation
Split the create-draft and publish steps of the Zenodo-to-Dataverse mirror into two deliberate actions. The new fwl-io mirror-publish subcommand and publish_existing_dataverse_draft() publish an existing draft by its persistent id and never create a dataset, so publishing is a separate, auditable step run after a draft has been reviewed. The persistent id must be of the form doi:<prefix>/<suffix>; a value that lacks the prefix, the slash, or either part is rejected locally with ValueError before any network call. The mirror-publish.yaml workflow targets the default Dataverse URL and binds every dispatch input to an environment variable, so a crafted input cannot redirect the API token or inject a shell command. Covered by unit tests for the never-creates-a-dataset property, the persistent-id validation, and the CLI wiring; docs/Reference/cli.md and docs/How-to/mirror_dataset.md document the subcommand.
The --version-type argparse choice bypassed the CLI's own exit-1 error contract by exiting 2 straight from argument parsing. Validate it inside publish_existing_dataverse_draft instead, alongside the existing persistent_id check, and restrict the workflow_dispatch input to the same two values. Also fixes a stale mirror_dataset.md reference to a dataverse_url input the publish workflow no longer takes, and tightens the persistent_id test coverage to include an empty-prefix DOI.
A whitespace-corrupted persistent id like 'doi: 10.34894/DEMO01' passed local validation and only failed later against the live Dataverse API; publish_existing_dataverse_draft now rejects any persistent id that contains whitespace. Adds a test for the version_type/persistent_id check order (version_type is checked first, so an invalid persistent id combined with an invalid version_type surfaces the version_type error). Also folds the two identical --dataverse-url defaults in cli.py's mirror and mirror-publish subparsers into one DEFAULT_DATAVERSE_URL constant.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a
mirror-publishsubcommand that publishes an existing Dataverse draft dataset. It is publish-only and never creates a dataset. It takes a persistent identifier, calls the Dataverse native publish endpoint, and reports the published identifier.publish_existing_dataverse_draftvalidatesversion_typeagainst('major', 'minor'), then the persistent identifier (must start withdoi:, split into a non-empty prefix and suffix around a single/, and contain no whitespace), then callsDataverseClient(...).publish(...). The CLI readsDATAVERSE_TOKENfrom the environment and exits with an error if it is unset; the token is never a command-line argument.A
mirror-publish.yamlworkflow exposes the command throughworkflow_dispatch, with inputspersistent_idandversion_type(choice ofmajororminor, defaultmajor). Both inputs bind to environment variables, not shell interpolation, so a crafted input cannot inject shell commands.New unit tests cover the never-creates-a-dataset guarantee, argument forwarding, an already-published dataset (403), a non-JSON success body, malformed identifiers, invalid version types, the order of the two checks, a nonexistent identifier (404), and the CLI wiring. The 23
mirror-publishandpublish_existingtests pass against this branch.docs/Reference/cli.mdanddocs/How-to/mirror_dataset.mddocument the subcommand.