Skip to content

Commit

Permalink
Convert script to a proper package
Browse files Browse the repository at this point in the history
Signed-off-by: Facundo Tuesca <facundo.tuesca@trailofbits.com>
  • Loading branch information
facutuesca committed Dec 6, 2024
1 parent 2953cf5 commit b026d5d
Show file tree
Hide file tree
Showing 16 changed files with 1,333 additions and 53 deletions.
20 changes: 20 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version: 2

updates:
- package-ecosystem: pip
directory: /
groups:
python:
patterns:
- "*"
schedule:
interval: daily

- package-ecosystem: github-actions
directory: /
groups:
actions:
patterns:
- "*"
schedule:
interval: daily
25 changes: 25 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Lint

on:
push:
branches:
- main
pull_request:

jobs:
lint:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./convert-attestations
steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
cache-dependency-glob: convert-attestations/pyproject.toml

- name: lint
run: make lint INSTALL_EXTRA=lint
32 changes: 32 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Unit tests

on:
push:
branches:
- main
pull_request:

jobs:
test-python-package:
strategy:
matrix:
python:
- "3.13"
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./convert-attestations
steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
cache-dependency-glob: convert-attestations/pyproject.toml

- name: Install Python ${{ matrix.python }}
run: uv python install ${{ matrix.python }}

- name: test
run: make test INSTALL_EXTRA=test
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
env/
pip-wheel-metadata/
*.egg-info/
__pycache__/
.coverage*
.idea
html/
dist/
26 changes: 1 addition & 25 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Expand Down Expand Up @@ -174,28 +175,3 @@
of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Adapt sigstore PyPI GitHub Action

<!--- BADGES: START --->
[![CI](https://github.com/trailofbits/gh-action-adapt-sigstore-pypi/actions/workflows/tests.yml/badge.svg)](https://github.com/trailofbits/gh-action-adapt-sigstore-pypi/actions/workflows/tests.yml)
<!--- BADGES: END --->

This action converts the Sigstore bundles generated by the [attest-build-provenance](https://github.com/actions/attest-build-provenance) GitHub action into PyPI attestations.

## Inputs
Expand Down
3 changes: 2 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ runs:
- name: Convert attestations
shell: bash
run: |
uv run --prerelease=allow ${{ github.action_path }}/convert-attestations.py \
uv install ${{ github.action_path }}/convert-attestations/
uv run convert-attestations
${{ inputs.output-dir != '' && format('--output-dir {0}', inputs.output-dir) || '' }} \
${{ inputs.bundles }}
86 changes: 86 additions & 0 deletions convert-attestations/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
SHELL := /bin/bash

PY_IMPORT = convert_attestations

ALL_PY_SRCS := $(shell find src -name '*.py') \
$(shell find test -name '*.py')

# Optionally overriden by the user, if they're using a virtual environment manager.
VENV ?= env

# On Windows, venv scripts/shims are under `Scripts` instead of `bin`.
VENV_BIN := $(VENV)/bin
ifeq ($(OS),Windows_NT)
VENV_BIN := $(VENV)/Scripts
endif

# Optionally overridden by the user in the `release` target.
BUMP_ARGS :=

# Optionally overridden by the user in the `test` target.
TESTS :=

# Optionally overridden by the user/CI, to limit the installation to a specific
# subset of development dependencies.
INSTALL_EXTRA := dev

# If the user selects a specific test pattern to run, set `pytest` to fail fast
# and only run tests that match the pattern.
# Otherwise, run all tests and enable coverage assertions, since we expect
# complete test coverage.
ifneq ($(TESTS),)
TEST_ARGS := -x -k $(TESTS)
COV_ARGS :=
else
TEST_ARGS :=
COV_ARGS := --fail-under 100
endif

.PHONY: all
all:
@echo "Run my targets individually!"

.PHONY: dev
dev: $(VENV)/pyvenv.cfg
.PHONY: run
run: $(VENV)/pyvenv.cfg
# Once we can specify the default VENV name in uv, use `uv run` here
# https://github.com/astral-sh/uv/issues/1422
@. $(VENV_BIN)/activate && convert-attestations $(ARGS)

$(VENV)/pyvenv.cfg: pyproject.toml
uv venv $(VENV)
@. $(VENV_BIN)/activate && uv pip install -e '.[$(INSTALL_EXTRA)]'

.PHONY: lint
lint: $(VENV)/pyvenv.cfg
. $(VENV_BIN)/activate && \
ruff format --check && \
ruff check && \
mypy
. $(VENV_BIN)/activate && \
interrogate -c pyproject.toml .

.PHONY: reformat
reformat:
. $(VENV_BIN)/activate && \
ruff format && \
ruff check --fix

.PHONY: test tests
test tests: $(VENV)/pyvenv.cfg
. $(VENV_BIN)/activate && \
pytest --cov=$(PY_IMPORT) $(T) $(TEST_ARGS) && \
python -m coverage report -m $(COV_ARGS)

.PHONY: doc
doc:
@echo "No documentation set up"

.PHONY: package
package: $(VENV)/pyvenv.cfg
uv build

.PHONY: edit
edit:
$(EDITOR) $(ALL_PY_SRCS)
94 changes: 94 additions & 0 deletions convert-attestations/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
[project]
name = "convert-attestations"
dynamic = ["version"]
description = ""
readme = "README.md"
license = { file = "LICENSE" }
authors = [
{ name = "Trail of Bits", email = "opensource@trailofbits.com" },
]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: Apache Software License",
]
dependencies = ["pypi-attestations == 0.0.19"]
requires-python = ">=3.13"

[tool.setuptools.dynamic]
version = { attr = "convert_attestations.__version__" }

[project.optional-dependencies]
doc = []
test = ["pytest", "pytest-cov", "pretend", "coverage[toml]"]
lint = [
# NOTE: ruff is under active development, so we pin conservatively here
# and let Dependabot periodically perform this update.
"ruff ~= 0.6.2",
"mypy >= 1.0",
"types-html5lib",
"types-requests",
"types-toml",
"interrogate",
]
dev = ["convert-attestations[doc,test,lint]", "twine", "build"]

[project.scripts]
"convert-attestations" = "convert_attestations._cli:main"

[project.urls]
Homepage = "https://pypi.org/project/convert-attestations"
Documentation = "https://trailofbits.github.io/convert-attestations/"
Issues = "https://github.com/trailofbits/convert-attestations/issues"
Source = "https://github.com/trailofbits/convert-attestations"

[tool.coverage.run]
# don't attempt code coverage for the CLI entrypoints
omit = ["src/convert_attestations/_cli.py"]

[tool.mypy]
mypy_path = "src"
packages = "convert_attestations"
allow_redefinition = true
check_untyped_defs = true
disallow_incomplete_defs = true
disallow_untyped_defs = true
ignore_missing_imports = true
no_implicit_optional = true
show_error_codes = true
sqlite_cache = true
strict_equality = true
warn_no_return = true
warn_redundant_casts = true
warn_return_any = true
warn_unreachable = true
warn_unused_configs = true
warn_unused_ignores = true

[tool.ruff]
line-length = 100
include = ["src/**/*.py", "test/**/*.py"]

[tool.ruff.lint]
select = ["ALL"]
# D203 and D213 are incompatible with D211 and D212 respectively.
# COM812 and ISC001 can cause conflicts when using ruff as a formatter.
# See https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules.
ignore = ["D203", "D213", "COM812", "ISC001"]

[tool.ruff.lint.per-file-ignores]
"src/convert_attestations/_cli.py" = [
"T201", # allow `print` in cli module
]
"test/**/*.py" = [
"D", # no docstrings in tests
"S101", # asserts are expected in tests
]
[tool.interrogate]
# don't enforce documentation coverage for packaging, testing, the virtual
# environment, or the CLI (which is documented separately).
exclude = ["env", "test", "src/convert_attestations/_cli.py"]
ignore-semiprivate = true
fail-under = 100

[tool.uv]
prerelease = "allow"
3 changes: 3 additions & 0 deletions convert-attestations/src/convert_attestations/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""The `convert-attestations` APIs."""

__version__ = "0.0.1"
6 changes: 6 additions & 0 deletions convert-attestations/src/convert_attestations/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"""The `python -m convert-attestations` entrypoint."""

if __name__ == "__main__": # pragma: no cover
from convert_attestations._cli import main

main()
Loading

0 comments on commit b026d5d

Please sign in to comment.