Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: publish wheels to testpypi #130

Closed
wants to merge 14 commits into from
47 changes: 47 additions & 0 deletions .github/workflows/release-testpypi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
name: publish wheels to testpypi

on: push
# TODO(retr0h): will enable prior to merge, testing action
# push:
# branches:
# - main
# # Allows you to run this workflow manually from the Actions tab
# workflow_dispatch:

jobs:
release:
runs-on: ubuntu-latest

environment:
name: testpypi
url: https://test.pypi.org/p/python-gilt

permissions:
# mandatory for trusted publishing
id-token: write

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: git fetch --force --tags
- uses: actions/setup-go@v5
with:
go-version: stable
- uses: goreleaser/goreleaser-action@v5
with:
distribution: goreleaser
version: latest
args: release --clean --snapshot
- name: Install Task
uses: arduino/setup-task@v1
with:
version: 3.x
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Build Wheels
run: task build:wheel
- uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
packages-dir: dist/whl/
6 changes: 2 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
---
name: goreleaser
name: publish packages
on:
push:
tags:
- "v*"

permissions:
contents: write
# packages: write
# issues: write

jobs:
goreleaser:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
__pycache__
cobertura.xml
cover.out
dist/
Expand Down
2 changes: 1 addition & 1 deletion .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ archives:
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}.dev"
name_template: "{{ incpatch .Version }}.dev0"
changelog:
sort: asc
filters:
Expand Down
76 changes: 53 additions & 23 deletions python/dist2wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
WHEEL_TEMPLATE = """Wheel-Version: 1.0
Generator: dist2wheel.py
Root-Is-Purelib: false
Tag: {py_tag}-{abi_tag}-{platform_tag}
Tag: {py_tag}-{abi_tag}-{platform_tag}
"""
METADATA_TEMPLATE = """Metadata-Version: 2.1
Name: {distribution}
Expand All @@ -43,18 +43,20 @@

class Wheels:
def __init__(self):
self.dist_dir = "dist"
self.wheel_dir = os.path.join(self.dist_dir, "whl")
# Pull in all the project metadata from known locations.
# No, this isn't customizable. Cope.
with open("dist/metadata.json") as f:
with open(os.path.join(self.dist_dir, "metadata.json")) as f:
self.metadata = json.load(f)

with open("dist/artifacts.json") as f:
with open(os.path.join(self.dist_dir, "artifacts.json")) as f:
self.artifacts = json.load(f)

with open("README.md") as f:
self.readme = f.read()

self.distribution = self.metadata["project_name"]
self.distribution = f"python-{self.metadata['project_name']}"
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be wise to double-check that the result files here are still installable, calling the package go-gilt seemed to piss it off; this might do the same

Copy link
Owner Author

Choose a reason for hiding this comment

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

Yeah, I wont merge any of this without you verifying my hacks

self.version = self.metadata["version"]
self.py_tag = "py3"
self.abi_tag = "none"
Expand All @@ -70,36 +72,55 @@ def create_all(self):

# We're looking for "internal_type: 2" artifacts, but being an internal
# type, we'll avoid leaning on implementation details if we don't have to
# for artifact in self.artifacts:
for artifact in self.artifacts:
try:
self.path = artifact["path"]
self.platform_tag = self._fixup_platform_tag(artifact)
self._set_platform_props(artifact)
self.checksum = self._fix_checksum(artifact["extra"]["Checksum"])
self.size = os.path.getsize(self.path)
except KeyError:
continue

self.wheel_file = WHEEL_TEMPLATE.format(**self.__dict__).encode()
self.metadata_file = METADATA_TEMPLATE.format(**self.__dict__).encode()
os.makedirs(self.wheel_dir, exist_ok=True)
self._emit()

@staticmethod
def _fixup_platform_tag(artifact):
def _matrix(self):
return {
"darwin": {
"amd64": {
"arch": "x86_64",
"platform": "macosx_10_7_x86_64",
"tags": [
f"{self.py_tag}-{self.abi_tag}-macosx_10_7_x86_64",
],
},
},
"linux": {
"amd64": {
"arch": "x86_64",
"platform": "manylinux2014_x86_64.manylinux_2_17_x86_64.musllinux_1_1_x86_64",
"tags": [
f"{self.py_tag}-{self.abi_tag}-manylinux2014_x86_64",
f"{self.py_tag}-{self.abi_tag}-manylinux_2_17_x86_64",
f"{self.py_tag}-{self.abi_tag}-musllinux_1_1_x86_64",
],
},
},
}

def _set_platform_props(self, artifact):
"""Convert Go binary nomenclature to Python wheel nomenclature."""

# Go 1.21 will require macOS 10.15 or later
_map = dict(darwin="macosx_10_15", linux="linux")
platform = _map[artifact["goos"]]

arch = artifact["goarch"]
if arch == "arm64" and platform == "linux":
arch = "aarch64"
elif arch == "amd64":
arch = "x86_64"
elif arch == "386":
arch = "i686"
_map = self._matrix()
_platform = artifact["goos"]
_goarch = artifact["goarch"]

return f"{platform}_{arch}"
platform = _map[_platform][_goarch]["platform"]
self.platform = f"{platform}"
self.platform_tag = "\n".join(_map[_platform][_goarch]["tags"])

@staticmethod
def _fix_checksum(checksum):
Expand All @@ -110,8 +131,13 @@ def _fix_checksum(checksum):
return base64.urlsafe_b64encode(bytes.fromhex(checksum)).decode().rstrip("=")

def _emit(self):
name_ver = f"{self.distribution}-{self.version}"
filename = f"dist/{name_ver}-{self.py_tag}-{self.abi_tag}-{self.platform_tag}.whl"
pypi_name = self.distribution.replace("-", "_")
name_ver = f"{pypi_name}-{self.version}"
filename = os.path.join(
self.wheel_dir,
f"{name_ver}-{self.py_tag}-{self.abi_tag}-{self.platform}.whl",
)

with zipfile.ZipFile(filename, "w", compression=zipfile.ZIP_DEFLATED) as zf:
record = []
print(f"writing {zf.filename}")
Expand All @@ -125,13 +151,17 @@ def _emit(self):
arcname = f"{name_ver}.dist-info/METADATA"
zf.writestr(arcname, self.metadata_file)
digest = hashlib.sha256(self.metadata_file).hexdigest()
record.append(f"{arcname},sha256={self._fix_checksum(digest)},{len(self.metadata_file)}")
record.append(
f"{arcname},sha256={self._fix_checksum(digest)},{len(self.metadata_file)}"
)

# The platform tags
arcname = f"{name_ver}.dist-info/WHEEL"
zf.writestr(arcname, self.wheel_file)
digest = hashlib.sha256(self.wheel_file).hexdigest()
record.append(f"{arcname},sha256={self._fix_checksum(digest)},{len(self.wheel_file)}")
record.append(
f"{arcname},sha256={self._fix_checksum(digest)},{len(self.wheel_file)}"
)

# Write out the manifest last. The record of itself contains no checksum or size info
arcname = f"{name_ver}.dist-info/RECORD"
Expand Down
Loading