Skip to content

Add Zenodo citation metadata and release verification - #37

Open
bernalde wants to merge 2 commits into
mainfrom
docs/issue-36-zenodo-citation
Open

Add Zenodo citation metadata and release verification#37
bernalde wants to merge 2 commits into
mainfrom
docs/issue-36-zenodo-citation

Conversation

@bernalde

@bernalde bernalde commented Jul 31, 2026

Copy link
Copy Markdown
Member

Summary

  • add schema-valid CFF metadata using the existing concept DOI as the evergreen MQLib.jl identifier
  • distinguish citations for this wrapper, upstream MQLib, exact wrapper releases, and the QUBO.jl ecosystem article
  • add a repeatable release checklist for Zenodo stewardship and archive-drift verification
  • add focused tests that keep the CFF, README, package version, and checklist aligned

Current Zenodo baseline

  • Concept DOI: https://doi.org/10.5281/zenodo.7511329
  • v0.7.3 DOI: https://doi.org/10.5281/zenodo.20926960
  • Release commit: 8ce413f76df2837466fdb6f0178606d75b541277
  • Zenodo archive SHA-256: 88dba8fa0685f7466f104ce4f0e470c1722fc3616ce6181b8432802cc538b35a
  • Zenodo archive MD5: 811642db432136a949ad601473cdefa3 (matches the public record)
  • Julia package UUID: 16f11440-1623-44c9-850c-358a6c72f3c9

The public Zenodo API reports v0.7.3 as the latest published version under
the existing concept DOI, with the expected repository, MIT license, creator
list, and one owner entry. The archive contains Project.toml version 0.7.3
and identifies the release commit above.

Acceptance criteria

  • Concept DOI 10.5281/zenodo.7511329 remains authoritative.
  • At least two maintainers have Can manage access. The public record
    currently exposes one owner entry, and no authenticated Zenodo credential
    is available to verify or add a second manager.
  • README and CFF consistently identify this repository as the wrapper and
    preserve separate attribution to upstream MQLib.
  • The release checklist detects concept/version, repository, tag/version,
    source-commit, checksum, and stewardship drift.

Because the second-manager criterion remains open, this PR uses Refs #36
instead of closing the issue. JuliaQUBO/QUBO.jl#66 remains the ecosystem-level
stewardship and citation-policy tracker.

Validation

  • uvx --cache-dir /tmp/mqlib-uv-cache --from cffconvert cffconvert --validate --infile CITATION.cff
    (cffconvert 2.0.0): valid against CFF schema 1.2.0
  • julia +1.10 --project=test -e 'using Test; include("test/citation.jl"); test_citation_metadata()':
    15/15 passed
  • julia +1.10 --project -e 'using Pkg; Pkg.test()': all package testsets passed
    (213 assertions); the existing optional upstream C++ syntax check skipped
    because MQLIB_UPSTREAM_DIR was not set
  • git -c core.whitespace=blank-at-eol,blank-at-eof,space-before-tab,cr-at-eol diff --check:
    passed (the README intentionally retains its existing mixed CRLF/LF endings)
  • GitHub Markdown rendering: citation links and the CFF link render correctly;
    both the canonical Zenodo badge and GitHub Camo badge display
    10.5281/zenodo.7511329
  • Zenodo API/archive verification: concept/version relation, creator list,
    repository, license, latest-version state, archive checksum, tagged version,
    and release commit all match

Branch Hygiene

  • Base branch: main
  • Source branch: docs/issue-36-zenodo-citation
  • Branch point: 7a56bc4e42c66cc980b6c2e566944d33e53b86ef
  • Stacked: no
  • Prerequisite PRs: none
  • Open-PR overlap: PR Make compatibility checks Dependabot-safe #33 also touches test/runtests.jl, but its compatibility
    assertions and this PR's end-of-file citation-test include are non-adjacent

Refs #36

@bernalde
bernalde marked this pull request as ready for review July 31, 2026 23:26

@bernalde bernalde left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial automated maintainer review

I reviewed head 32e543ad99c0e6730715f4d4718ebe20b2c88741 against issue #36 and the current main tip.

Findings

  • Blocking: none
  • Nonblocking: 1 inline line-ending cleanup
  • Questions: none

Validation

  • cffconvert --validate --infile CITATION.cff: valid against CFF 1.2.0
  • Focused citation test: 15/15 passed
  • Full local Julia 1.10 package suite: all testsets passed (213 assertions)
  • Current-head CI: all four jobs passed
  • GitHub-rendered README and both canonical/Camo DOI badges show the concept DOI
  • Live Zenodo metadata, archive checksum/content, release tag/commit, upstream MQLib paper DOI, and QUBO.jl article DOI match the PR claims
  • Local and GitHub changed-file sets match; the current-base merge probe and combined probe with overlapping PR #33 are conflict-free

Merge readiness

There are no blocking findings. This is a COMMENT review because the authenticated account authored the PR and cannot self-approve. main requires zero approving reviews, so no formal approval gate is enforced; the inline item is a small nonblocking cleanup before final human handoff.

Comment thread README.md Outdated
@@ -1,5 +1,5 @@
# MQLib.jl
[![DOI](https://zenodo.org/badge/568213607.svg)](https://zenodo.org/badge/latestdoi/568213607)
# MQLib.jl

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nonblocking: this hunk also converts the unchanged heading from CRLF to LF. The raw README diff is 23 additions/2 deletions, while --ignore-cr-at-eol is 22/1; the mixed-ending file moves from 40 CRLF + 26 LF lines to 38 CRLF + 49 LF lines. Please restore the original CRLF ending on the unchanged heading and retain CRLF on the edited badge line, so this PR changes badge content without incidental line-ending churn.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 4e9d9d9. The heading and edited DOI badge line again use CRLF, preserving the base file's 40 CRLF lines; only the 21 newly added README lines use LF. The raw and --ignore-cr-at-eol PR diffs now both report 22 additions / 1 deletion. The full 213-assertion Julia suite and all four current-head CI jobs pass. I have left this thread unresolved for human confirmation.

@bernalde

Copy link
Copy Markdown
Member Author

Addressed the review finding in 4e9d9d9 by restoring CRLF endings on the unchanged README heading and the edited DOI badge line. The raw and --ignore-cr-at-eol README diffs now agree at 22 additions / 1 deletion, so the remaining change is content-only.

Validation for this head:

  • full Julia 1.10 package suite: 213/213 assertions passed
  • CRLF-aware git diff --check: passed
  • all four current-head CI jobs: passed (native C ABI, Julia 1.10/Linux, Julia current/Linux, Julia current/Windows)

No review items were declined. The second-Zenodo-manager acceptance criterion remains an external human action, and the review thread is intentionally left unresolved for human confirmation.

@bernalde bernalde left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maintainer re-review of head 4e9d9d9

Re-review after the line-ending fix pushed on top of the head I reviewed previously (32e543a, review 4832824388). The incremental diff 32e543a..4e9d9d9 is 2 insertions / 2 deletions in README.md only, but the full changed-file set was re-verified and the suite re-run at this head.

Prior finding

  • Resolved. The README line-ending churn is gone. At this head git diff --numstat and git diff --numstat --ignore-cr-at-eol against the merge base both report 22 1 for README.md, so the raw diff no longer contains EOL-only churn on the unchanged heading. The corresponding thread is outdated but still open; resolving it is currently the only merge gate (see below).

Two new blocking findings follow. Both are in .github/RELEASE_CHECKLIST.md, which is the operational deliverable for issue #36's "detects archival drift" criterion — the code, metadata, and tests themselves are sound.

Findings

  • Blocking (inline, .github/RELEASE_CHECKLIST.md:24): the checklist tells maintainers to manually create a new version from the Zenodo record, but this repository's Zenodo–GitHub integration already does that automatically when TagBot publishes the release. Following the step produces a duplicate deposit.
  • Blocking (inline, .github/RELEASE_CHECKLIST.md:32): no step refreshes the version DOI that this PR hardcodes in CITATION.cff, README.md, and test/citation.jl, and the test constant makes the resulting staleness invisible to CI.
  • Nonblocking (inline, test/citation.jl:42): two assertions pin prose wording of a maintainer-only document into the shipped package test suite.

Verified as claimed

  • CITATION.cff is schema-valid: cffconvert --validate --infile CITATION.cff (cffconvert 2.0.0) reports "Citation metadata are valid according to schema version 1.2.0".
  • All four DOIs resolve and match their descriptions. Crossref confirms 10.1287/ijoc.2017.0798 is Dunning, Gupta, Silberholz, "What Works Best When? A Systematic Evaluation of Heuristics for Max-Cut and QUBO" (INFORMS Journal on Computing), and 10.1080/10556788.2026.2702926 is the QUBO.jl ecosystem article in Optimization Methods and Software.
  • The concept/version relation holds: record 20926960 reports conceptdoi: 10.5281/zenodo.7511329 and metadata.version: v0.7.3.
  • The CFF author roster matches the Zenodo creator list in both membership and order (David Bernal, Pedro Maciel Xavier, Pedro Ripper). Both ORCIDs resolve to the named people via the ORCID public API.
  • The unmet acceptance criterion is accurately reported: the Zenodo record exposes exactly one owners entry, so Refs #36 rather than Closes #36 is the correct link.
  • Open-PR overlap is as described. PR #33 also touches test/runtests.jl, but only the "Compatibility metadata" testset near line 180; git merge-tree --write-tree against PR #33's head is conflict-free.

Tests run

  • julia --project -e 'using Pkg; Pkg.test()' at 4e9d9d9: passed — Compatibility metadata 6, QUBODrivers 141, Julia C ABI bridge 30, C ABI contract 21, Citation metadata 15 (213 total). The optional upstream C++ syntax check skipped because MQLIB_UPSTREAM_DIR is unset, as expected.
  • Current-head GitHub checks: all four pass (Julia 1 - ubuntu-latest, Julia 1 - windows-latest, Julia 1.10 - ubuntu-latest, Native C ABI smoke test). No skipped or failing checks.
  • Merge-result probe: the PR is not behind its base — git merge-base origin/main HEAD equals the current main tip 7a56bc4, so the head diff is the merge result.
  • Local and GitHub changed-file sets match exactly (6 files).

Merge readiness

This is a COMMENT review because the authenticated account authored the PR; GitHub rejects APPROVE and REQUEST_CHANGES from the author. Treat it as a request for changes on the two blocking items.

Branch protection on main requires 0 approving reviews, so no approval gate applies. It does enable required_conversation_resolution, which is why mergeStateStatus is BLOCKED — and posting this review adds three more unresolved threads, so thread resolution rather than approval is the standing merge gate.

I would not merge this until the blocking issues above are addressed.

Comment on lines +24 to +25
- [ ] Create a **new version** from the existing Zenodo record; do not create a
new upload or concept DOI.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: this step prescribes a manual deposit, but this repository's Zenodo archive is already created automatically, and following the step literally produces a duplicate record.

Evidence that the Zenodo–GitHub integration is enabled and did the work for v0.7.3:

  • the README badge this PR replaces was zenodo.org/badge/568213607.svg, and gh api repos/JuliaQUBO/MQLib.jl --jq .id returns 568213607 — that badge is keyed on the GitHub repository id, so the integration is wired up;
  • record 20926960 carries related_identifiers: [{relation: "isSupplementTo", identifier: "https://github.com/JuliaQUBO/MQLib.jl/tree/v0.7.3"}], and its description is the auto-copied GitHub release notes (MQLib v0.7.3 / Diff since v0.7.2 / Merged pull requests:);
  • .github/workflows/tagbot.yml runs JuliaRegistries/TagBot@v1, so the GitHub release itself is created automatically after registration.

The real chain is Registrator → TagBot publishes the GitHub release → Zenodo auto-archives a new version under the concept DOI. A maintainer who instead opens the record and clicks New version deposits a second archive for the same release — exactly the drift the rest of this checklist exists to prevent. Reframing the step as verification also makes the following steps coherent, since with the integration there is no pre-publication window in which to edit the deposit.

Suggested change
- [ ] Create a **new version** from the existing Zenodo record; do not create a
new upload or concept DOI.
- [ ] Confirm the Zenodo GitHub integration published a **new version** under
the existing concept record automatically when TagBot created the GitHub
release. Do not deposit a new upload or concept DOI by hand; if the
integration is ever disabled, re-enable it rather than archiving
manually.

If the integration was deliberately turned off and manual deposits are the intended workflow, say so here — but then the v0.7.3 record's provenance above needs explaining.

Comment on lines +32 to +33
- [ ] Publish the Zenodo version and record its version DOI in the GitHub
release notes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: the refresh instructions omit the three places this PR hardcodes the version DOI, so the next release ships citation metadata still pointing at the v0.7.3 archive.

"Before tagging" updates only Project.toml, the CFF version/date-released, and CHANGELOG.md; this step then records the new version DOI in the GitHub release notes and nowhere else. After the next release the repository still says:

  • CITATION.cffidentifiers[0].value: "10.5281/zenodo.20926960" with description: "Zenodo DOI for version 0.7.3"
  • README.md — "The archive for MQLib.jl v0.7.3 is [10.5281/zenodo.20926960]"
  • test/citation.jl:16version_doi = "10.5281/zenodo.20926960"

test/citation.jl cannot catch this, because version_doi is a constant asserted against both the CFF and the README: all three artifacts stay self-consistently stale and the suite stays green. The reverse case is worse — a maintainer who correctly updates the CFF and README breaks Pkg.test() until they also edit the test constant, and nothing in the checklist tells them that file is in scope.

Suggested change
- [ ] Publish the Zenodo version and record its version DOI in the GitHub
release notes.
- [ ] Publish the Zenodo version and record its version DOI in the GitHub
release notes.
- [ ] Update the new version DOI everywhere it is pinned: the `identifiers`
entry and its `description` in `CITATION.cff`, the exact-version archive
sentence in the README "Citation" section, and `version_doi` in
`test/citation.jl`. Re-run
`julia --project -e 'using Pkg; Pkg.test()'`.

Comment thread test/citation.jl
Comment on lines +42 to +43
Test.@test occursin("<version-doi>", checklist)
Test.@test occursin("metadata.version", checklist)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nonblocking: these two assertions pin editorial wording in a maintainer-only document rather than a contract, so a harmless reword of the checklist fails Pkg.test() for every downstream user and in General-registry test runs.

<version-doi> is a placeholder inside an example curl invocation and metadata.version is one field named in a prose paragraph; either can be rephrased without weakening the checklist at all. Reading .github/ from the test suite is established convention here — the existing "Compatibility metadata" testset reads ci.yml — but that one asserts a real pin (version: '1.10') that must not drift.

Suggest keeping the checks that carry contract value (the concept DOI on line 36 and the cffconvert --validate command on lines 38-41, both of which encode decisions the issue asked for) and dropping these two.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant