Skip to content

fix: resolve LICENSE conflict, upgrade to PyPI Trusted Publishing, add CHANGELOG#4

Merged
samdporter merged 2 commits intomainfrom
copilot/fix-license-merge-conflict
Apr 15, 2026
Merged

fix: resolve LICENSE conflict, upgrade to PyPI Trusted Publishing, add CHANGELOG#4
samdporter merged 2 commits intomainfrom
copilot/fix-license-merge-conflict

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 15, 2026

Three blockers preventing clean PyPI publication: a corrupt LICENSE file with unresolved merge conflicts, an API-token-based publish workflow, and no changelog.

Changes

  • LICENSE — Stripped merge conflict markers (<<<<<<< HEAD / ======= / >>>>>>>); replaced with a single clean Apache 2.0 text under Copyright 2024 Sam Porter, Efstathios Varzakis.

  • .github/workflows/publish.yml — Migrated to PyPI Trusted Publishing: added permissions: id-token: write at job level, removed password: ${{ secrets.PYPI_API_TOKEN }}.

    permissions:
      id-token: write
    ...
    - name: Publish to PyPI
      uses: pypa/gh-action-pypi-publish@release/v1   # no `with: password:` block
  • CHANGELOG.md — New file in Keep a Changelog format with a [0.5.0] entry.

  • pyproject.toml — Added Changelog URL under [project.urls].

Manual step required: Register a GitHub Trusted Publisher on PyPI for py-smc (owner: samdporter, repo: SIRF-SIMIND-Connection, workflow: publish.yml) before triggering a release.

Original prompt

Problems to Fix

1. Resolve merge conflict in LICENSE

The LICENSE file currently contains unresolved Git merge conflict markers (<<<<<<< HEAD, =======, >>>>>>> origin/main), which means the file is corrupt. This will cause twine check to fail and block PyPI publishing.

The file contains two copies of the Apache 2.0 license text. The correct resolution is to keep a single, clean copy of the Apache 2.0 license. The correct copyright line (from the HEAD version) is:

Copyright 2024 Sam Porter, Efstathios Varzakis

Please replace the entire contents of LICENSE with a single clean copy of the Apache 2.0 license text with that copyright line. Remove all merge conflict markers.


2. Upgrade publish workflow to PyPI Trusted Publishing

Update .github/workflows/publish.yml to use PyPI Trusted Publishing instead of the PYPI_API_TOKEN secret. This is the modern, more secure approach.

The updated workflow should:

  • Add permissions: id-token: write at the job level
  • Remove the password: ${{ secrets.PYPI_API_TOKEN }} line from the pypa/gh-action-pypi-publish step
  • Keep everything else the same (trigger on release, build with python -m build, check with twine check)

The final publish step should look like:

- name: Publish to PyPI
  uses: pypa/gh-action-pypi-publish@release/v1

3. Add a CHANGELOG.md

Create a CHANGELOG.md in the root of the repo following Keep a Changelog format. Include an entry for the current version 0.5.0 with a summary of what the package does (Python SIMIND Monte Carlo connector with STIR/SIRF/PyTomography adaptors for SPECT imaging).

Also add the changelog URL to pyproject.toml under [project.urls]:

Changelog = "https://github.com/samdporter/SIRF-SIMIND-Connection/blob/main/CHANGELOG.md"

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: How close is this to being publishable on PyPI?

Assistant: This repo is very close to being publishable on PyPI — probably 85–90% of the way there. The packaging infrastructure is well set up. Here's a full breakdown:


✅ What's Already Done

Area Status
pyproject.toml ✅ Complete — name, version, description, authors, classifiers, license, dependencies, URLs
setup.py ✅ Thin shim for backwards compat
MANIFEST.in ✅ Includes data files, docs, tests
Package data (.atn files) ✅ Declared in pyproject.toml
Python version support ✅ 3.9–3.12 declared and tested in CI
README.md ✅ Present and referenced as long description
LICENSE ✅ Apache 2.0 (though see issue below)
Optional deps ([dev], [examples]) ✅ Clean
GitHub Actions publish workflow ✅ Triggers on GitHub release, uses pypa/gh-action-pypi-publish
CI build check (twine check dist/*) ✅ Already runs on every push
ReadTheDocs config ✅ Present
__version__ ✅ Reads from package metadata at runtime

🚨 Blockers (Must Fix Before Publishing)

1. Git merge conflicts in LICENSE file (critical)

The LICENSE file has unresolved merge conflict markers (<<<<<<< HEAD, =======, >>>>>>> origin/main). This will cause twine check to fail or produce a broken distribution. You need to resolve this immediately.

<<<<<<< HEAD         ← ⚠️ merge conflict marker — MUST be removed
Apache License
Version 2.0...
=======
                                 Apache License    ← duplicate content

2. PYPI_API_TOKEN secret not verified

The publish workflow uses ${{ secrets.PYPI_API_TOKEN }}. You'll need to either:

  • Create an API token at pypi.org and add it as a repo secret, or
  • Switch to Trusted Publishing (the modern, recommended approach — no token needed).

3. Package name py-smc may already be taken on PyPI

The name in pyproject.toml is py-smc. You should verify it's available at pypi.org/project/py-smc before publishing.


⚠️ Recommended Improvements

4. License classifier mismatch

pyproject.toml has license = "Apache-2.0" (SPDX string format, valid for modern setuptools), but GitHub shows the license as "Other" — this is likely because of the merge conflict corrupting the file. Fix the LICENSE file and GitHub/PyPI will correctly identify it as Apache 2.0.

5. No CHANGELOG / release notes

PyPI users appreciate a changelog. Consider adding CHANGELOG.md and linking it in pyproject.toml under [project.urls].

6. No CONTRIBUTING.md or CODE_OF_CONDUCT.md

Not required for PyPI, but good for an open-source project of this scope.

7. **Trusted Publishing (optional but recommended)...

This pull request was created from Copilot chat.

Summary by Sourcery

Resolve packaging and licensing blockers for PyPI publication.

New Features:

  • Add a project changelog in Keep a Changelog format documenting version 0.5.0.

Enhancements:

  • Clean up the LICENSE file to contain a single, valid Apache 2.0 license text.
  • Update the PyPI publish workflow to use PyPI Trusted Publishing via OIDC instead of an API token.
  • Link the changelog from project metadata in pyproject.toml under project URLs.

Copilot AI changed the title [WIP] Fix merge conflict in LICENSE file and update publish workflow fix: resolve LICENSE conflict, upgrade to PyPI Trusted Publishing, add CHANGELOG Apr 15, 2026
Copilot AI requested a review from samdporter April 15, 2026 11:19
@samdporter samdporter marked this pull request as ready for review April 15, 2026 11:28
Copilot AI review requested due to automatic review settings April 15, 2026 11:28
@samdporter samdporter merged commit 26b79e0 into main Apr 15, 2026
5 checks passed
@samdporter samdporter deleted the copilot/fix-license-merge-conflict branch April 15, 2026 11:28
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Apr 15, 2026

Reviewer's Guide

This PR resolves PyPI publication blockers by fixing the corrupted LICENSE, migrating the release workflow to PyPI Trusted Publishing, and adding a formal changelog linked from pyproject.toml.

Sequence diagram for PyPI Trusted Publishing workflow

sequenceDiagram
    actor Maintainer
    participant GitHubRepo
    participant GitHubActions
    participant GitHubOIDC
    participant PyPI

    Maintainer->>GitHubRepo: Create GitHub release
    GitHubRepo-->>GitHubActions: Trigger publish workflow

    GitHubActions->>GitHubActions: Build distribution (python -m build)
    GitHubActions->>GitHubActions: Run twine check dist/*

    GitHubActions->>GitHubOIDC: Request id-token (permissions id-token: write)
    GitHubOIDC-->>GitHubActions: Signed OIDC id-token

    GitHubActions->>PyPI: Publish via pypa/gh-action-pypi-publish@release/v1 using id-token
    PyPI-->>GitHubActions: Validate trusted publisher and accept upload
    GitHubActions-->>Maintainer: Publish job completes
Loading

Flow diagram for release-to-PyPI pipeline with Trusted Publishing

flowchart LR
    A[Maintainer creates GitHub release] --> B[GitHub Actions triggers publish job]
    B --> C[Set up Python and dependencies]
    C --> D[Build package with python -m build]
    D --> E[Run twine check dist/*]
    E --> F[Request OIDC id-token
permissions id-token: write]
    F --> G[Call pypa/gh-action-pypi-publish@release/v1
with id-token]
    G --> H[PyPI validates trusted publisher
and uploads py-smc]
    H --> I[Release available on PyPI]
Loading

File-Level Changes

Change Details Files
Clean up the LICENSE file so it contains a single valid Apache 2.0 license text without merge conflict artifacts.
  • Removed all Git merge conflict markers and duplicate license sections.
  • Replaced the file contents with a single, canonical Apache 2.0 license body.
  • Ensured the copyright line is set to "Copyright 2024 Sam Porter, Efstathios Varzakis".
LICENSE
Update the GitHub Actions publish workflow to use PyPI Trusted Publishing instead of a static API token.
  • Granted the publish job OIDC permission via permissions: id-token: write.
  • Kept the existing build (python -m build) and twine check steps intact.
  • Simplified the publish step to use pypa/gh-action-pypi-publish@release/v1 without a password input, removing reliance on PYPI_API_TOKEN.
  • Documented the need for configuring a Trusted Publisher in PyPI before running the workflow.
.github/workflows/publish.yml
Introduce a Keep a Changelog–style CHANGELOG and expose it via project metadata.
  • Added a new CHANGELOG file following Keep a Changelog format with a 0.5.0 entry describing the package capabilities and features.
  • Linked the changelog from project metadata by adding a Changelog URL entry under [project.urls] in pyproject.toml.
CHANGELOG.md
pyproject.toml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path=".github/workflows/publish.yml" line_range="10-11" />
<code_context>
 jobs:
   publish:
     runs-on: ubuntu-latest
+    permissions:
+      id-token: write
     steps:
       - uses: actions/checkout@v4
</code_context>
<issue_to_address>
**issue (bug_risk):** Setting only `id-token: write` will revoke other default permissions and likely break `actions/checkout`.

Defining `permissions` overrides all defaults, so anything not listed is set to `none` (including `contents: read`), which `actions/checkout@v4` needs.

To keep checkout working while enabling OIDC for PyPI, you can set:

```yaml
jobs:
  publish:
    permissions:
      contents: read
      id-token: write
```

so the workflow still has read access to the repo while granting the required ID token permission.
</issue_to_address>

### Comment 2
<location path="CHANGELOG.md" line_range="17" />
<code_context>
+- Support for SIMIND `.atn` attenuation map data files.
+- Helper utilities for configuring and running SIMIND Monte Carlo simulations from Python.
+- Comprehensive test suite using `pytest`.
+- Documentation hosted on ReadTheDocs.
+- PyPI packaging (`py-smc`) with optional `dev` and `examples` dependency groups.
</code_context>
<issue_to_address>
**nitpick (typo):** Consider using the official service name "Read the Docs" instead of "ReadTheDocs".

The service’s official branding uses spaces: “Read the Docs.” Please update this bullet accordingly, e.g. “Documentation hosted on Read the Docs.”

```suggestion
- Documentation hosted on Read the Docs.
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +10 to +11
permissions:
id-token: write
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk): Setting only id-token: write will revoke other default permissions and likely break actions/checkout.

Defining permissions overrides all defaults, so anything not listed is set to none (including contents: read), which actions/checkout@v4 needs.

To keep checkout working while enabling OIDC for PyPI, you can set:

jobs:
  publish:
    permissions:
      contents: read
      id-token: write

so the workflow still has read access to the repo while granting the required ID token permission.

Comment thread CHANGELOG.md
- Support for SIMIND `.atn` attenuation map data files.
- Helper utilities for configuring and running SIMIND Monte Carlo simulations from Python.
- Comprehensive test suite using `pytest`.
- Documentation hosted on ReadTheDocs.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nitpick (typo): Consider using the official service name "Read the Docs" instead of "ReadTheDocs".

The service’s official branding uses spaces: “Read the Docs.” Please update this bullet accordingly, e.g. “Documentation hosted on Read the Docs.”

Suggested change
- Documentation hosted on ReadTheDocs.
- Documentation hosted on Read the Docs.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to remove remaining blockers for publishing py-smc to PyPI by cleaning up licensing artifacts, switching the release workflow to PyPI Trusted Publishing (OIDC), and adding a project changelog reference in package metadata.

Changes:

  • Add CHANGELOG.md and link it from pyproject.toml.
  • Update the GitHub Actions release workflow to publish via PyPI Trusted Publishing (OIDC) instead of an API token.
  • Resolve merge-conflict corruption in LICENSE (but see review comments about license text integrity).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
pyproject.toml Adds a Changelog URL under [project.urls].
LICENSE Removes conflict markers/duplicate content; currently contains non-canonical Apache 2.0 text.
CHANGELOG.md Introduces a Keep a Changelog–style changelog with a 0.5.0 entry.
.github/workflows/publish.yml Switches publish step to Trusted Publishing and adds OIDC permissions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread LICENSE
Comment on lines +35 to 39
"Work" shall mean the work of authorship made available under
the License, as indicated by a copyright notice that is included in
or attached to the work (an example is provided in the Appendix below).

"Derivative Works" shall mean any work, whether in Source or Object
jobs:
publish:
runs-on: ubuntu-latest
permissions:
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.

3 participants