Skip to content

chore: setup release, readthedocs#186

Merged
kessplas merged 5 commits into
stagingfrom
kessplas/release
May 18, 2026
Merged

chore: setup release, readthedocs#186
kessplas merged 5 commits into
stagingfrom
kessplas/release

Conversation

@kessplas

@kessplas kessplas commented May 15, 2026

Copy link
Copy Markdown
Contributor

Issue #, if available:

Description of changes: Adds release workflow to publish to TestPyPi and PyPi. This uses OIDC; we will need to configure OIDC/TrustedPublishing in PyPi for this to work. Also configures ReadTheDocs, which also needs external action to setup.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@kessplas kessplas marked this pull request as ready for review May 18, 2026 16:37
@lucasmcdonald3 lucasmcdonald3 requested a review from Copilot May 18, 2026 16:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Sets up the project's release tooling: a manually-triggered GitHub Actions release pipeline that uses semantic-release to determine the next version, publishes to TestPyPI then PyPI via OIDC/Trusted Publishing, runs a post-publish round-trip validation against AWS, and creates a GitHub release. Also adds Sphinx-based ReadTheDocs configuration and a docs optional-dependency extra so RTD can build the API reference.

Changes:

  • New release.yml workflow (determine-version → test → build → publish-testpypi → validate-testpypi → publish-pypi → validate-pypi → create-release) plus .releaserc.cjs configuring conventional-commits-driven versioning.
  • New release-validation/validate.py performing a KMS-keyring put/get round-trip against S3 using the installed wheel.
  • New Sphinx docs scaffolding (docs/conf.py, docs/index.rst, docs/api.rst), .readthedocs.yaml, and a docs extra in pyproject.toml.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
.github/workflows/release.yml New 7-job release pipeline gated on workflow_dispatch with optional version override / dry-run.
.releaserc.cjs semantic-release config: commit-analyzer, release notes, sed-based pyproject version bump, changelog, git, github.
release-validation/validate.py Post-publish smoke test that encrypts/decrypts a unique S3 object using the installed package.
.readthedocs.yaml RTD build config pinning Ubuntu 22.04 + Python 3.11 and installing the docs extra.
docs/conf.py Sphinx config with autodoc, napoleon (Google docstrings), intersphinx, RTD theme.
docs/index.rst Landing page with project blurb, getting-started snippet, and toctree to api.
docs/api.rst autodoc references for client, materials, keyring, and exceptions modules.
pyproject.toml Adds docs optional-dependency group (sphinx + sphinx-rtd-theme).

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

path: dist/
- uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
Comment thread .github/workflows/release.yml Outdated
Comment on lines +231 to +233
# Manual override: create a simple GitHub release
gh release create "v${{ needs.determine-version.outputs.version }}" \
--title "v${{ needs.determine-version.outputs.version }}" \
import boto3

from s3_encryption import S3EncryptionClient, S3EncryptionClientConfig
from s3_encryption._utils import _PACKAGE_VERSION
Comment on lines +39 to +52
# Put
print(f" Encrypting and uploading to s3://{BUCKET}/{key}")
s3ec.put_object(Bucket=BUCKET, Key=key, Body=plaintext)

# Get
print(f" Downloading and decrypting from s3://{BUCKET}/{key}")
response = s3ec.get_object(Bucket=BUCKET, Key=key)
result = response["Body"].read()

assert result == plaintext, f"Round-trip failed: expected {plaintext!r}, got {result!r}"

# Cleanup
s3_client.delete_object(Bucket=BUCKET, Key=key)

Comment thread .github/workflows/release.yml Outdated
Comment on lines +53 to +83
test:
name: Run Tests
needs: determine-version
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.10"
- run: pip install uv
- run: make install
- uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: arn:aws:iam::370957321024:role/S3EC-Python-Github-test-role
aws-region: us-west-2
- name: Unit tests
run: make test-unit
- name: Integration tests
run: make test-integration
env:
CI_S3_BUCKET: ${{ vars.CI_S3_BUCKET }}
CI_KMS_KEY_ALIAS: ${{ vars.CI_KMS_KEY_ALIAS }}
CI_MRK_KEY_ID_PRIMARY: ${{ vars.CI_MRK_KEY_ID_PRIMARY }}
CI_MRK_KEY_ID_REPLICA: ${{ vars.CI_MRK_KEY_ID_REPLICA }}
CI_S3_STATIC_TEST_BUCKET: ${{ vars.CI_S3_STATIC_TEST_BUCKET }}
CI_KMS_KEY_STATIC_TESTS: ${{ vars.CI_KMS_KEY_STATIC_TESTS }}
- name: Example tests
run: make test-examples
Comment on lines +46 to +55
echo "No release needed based on commits"
exit 1
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Semantic release determined version: $VERSION"
fi

test:
name: Run Tests
needs: determine-version

@lucasmcdonald3 lucasmcdonald3 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'm pretty sure we can make the docs private for now if we want to publish right? I think it'd be good to make sure the build works and docs look good before release but not strictly necessary

Comment thread .github/workflows/release.yml Outdated
persist-credentials: true
- uses: actions/setup-node@v4
with:
node-version: "20"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

20 is EOL can we bump this


import boto3

from s3_encryption import S3EncryptionClient, S3EncryptionClientConfig

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

For validate scripts we should just need a smoke test that the package is usable -- i.e. this import line is sufficient. My concern about a real integ test here is that it needs permissions which could be annoying to maintain. But just a personal preference and nbd

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think this is a bit easier to maintain in GHA since we have the same identity/permissions as CI. I'd rather have the coverage that something within the runtime isn't broken.

Comment on lines +230 to +237
if [ -n "${{ inputs.version_override }}" ]; then
# Manual override: create a simple GitHub release
gh release create "v${{ needs.determine-version.outputs.version }}" \
--title "v${{ needs.determine-version.outputs.version }}" \
--generate-notes
else
npx semantic-release
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I don't fully understand this in either path --

  • If we specify a version then the script will automatically publish a release right? Do we do this anywhere else? I thought we prefer to have the bot make a draft then humans review and click publish
  • What does running npx semantic-release do here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The Github releases can be a draft, I'll fix that in the next revision.

npx semantic-release does this. In short it commits the version change and creates a Github release.

The branch exists because if we give a manual override, we can't use semantic-release so we have to do the various steps manually. Notably, there is no CHANGELOG update when this happens, I'll make a note to mention this in the release process.

Comment thread .releaserc.cjs
[
"@semantic-release/git",
{
assets: ["pyproject.toml", "CHANGELOG.md"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Will this include the source code by default?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

If you mean the zip of source code in Github releases, that is done automatically by Github whenever a git tag exists.

Comment thread pyproject.toml Outdated
Comment on lines +27 to +28
"sphinx>=7.0",
"sphinx-rtd-theme>=2.0",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I might suggest pinning to major version here, I've been burned before

@kessplas kessplas merged commit 3d133b1 into staging May 18, 2026
21 checks passed
@kessplas kessplas deleted the kessplas/release branch May 18, 2026 23:55
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