From 77982fc7ac9a052fa18c525a9746b94e2d2d69f2 Mon Sep 17 00:00:00 2001 From: Chris Wagner Date: Sun, 4 Aug 2024 11:01:19 -0700 Subject: [PATCH] Build 2 different packages (#1019) Working on getting the same contents uploaded to 2 different pypi packages (flask-security and flask-security-too) This means 2 slightly different packages - just with a different 'name' - which means different pyproject.toml which requires a build tool that can handle that (build cant) - so moved to flit like many other pallets-eco. Using flit enabled moving the manifest into pyproject.toml and eliminating the MANIFEST file. Finally - different packages mean different provenance etc - so separated out the publishing action into 2 - one for each pypi. This means we will create 2 draft releases in github - but that should be ok. Note that the changing from MANIFEST could introduce slightly different contents... --- .github/workflows/publish-too.yaml | 73 +++++++++++++++++ .github/workflows/publish.yaml | 16 ---- LICENSE => LICENSE.txt | 0 MANIFEST.in | 24 ------ pyproject-too.toml | 124 +++++++++++++++++++++++++++++ pyproject.toml | 35 ++++++-- requirements/dev.txt | 2 +- tox.ini | 16 +++- 8 files changed, 239 insertions(+), 51 deletions(-) create mode 100644 .github/workflows/publish-too.yaml rename LICENSE => LICENSE.txt (100%) delete mode 100644 MANIFEST.in create mode 100644 pyproject-too.toml diff --git a/.github/workflows/publish-too.yaml b/.github/workflows/publish-too.yaml new file mode 100644 index 00000000..5abced53 --- /dev/null +++ b/.github/workflows/publish-too.yaml @@ -0,0 +1,73 @@ +name: Publish-Too +on: + push: + tags: + - '*' +jobs: + build: + runs-on: ubuntu-latest + outputs: + hash: ${{ steps.hash.outputs.hash }} + steps: + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + with: + python-version: '3.x' + cache: pip + cache-dependency-path: requirements*/*.txt + # Use the commit date instead of the current date during the build. + - run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV + - name: Create dist + run: | + python -m pip install -U pip + pip install tox + tox -e makedist-too + # Generate hashes used for provenance. + - name: generate hash + id: hash + run: cd dist && echo "hash=$(sha256sum * | base64 -w0)" >> $GITHUB_OUTPUT + - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + path: ./dist + provenance: + needs: [build] + permissions: + actions: read + id-token: write + contents: write + # Can't pin with hash due to how this workflow works. + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0 + with: + base64-subjects: ${{ needs.build.outputs.hash }} + create-release: + # Upload the sdist, wheels, and provenance to a GitHub release. They remain + # available as build artifacts for a while as well. + needs: [provenance] + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + - name: create release + run: > + gh release create --draft --repo ${{ github.repository }} + ${{ github.ref_name }}-Too + *.intoto.jsonl/* artifact/* + env: + GH_TOKEN: ${{ github.token }} + + publish-pypi-too: + needs: [ provenance ] + # Wait for approval before attempting to upload to PyPI. This allows reviewing the + # files in the draft release. + environment: + name: publish + url: https://pypi.org/project/Flask-Security-Too/${{ github.ref_name }} + runs-on: ubuntu-latest + permissions: + id-token: write + steps: + - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + - uses: pypa/gh-action-pypi-publish@81e9d935c883d0b210363ab89cf05f3894778450 # v1.8.14 + with: + packages-dir: artifact/ diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 73c22cc9..26b68579 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -70,19 +70,3 @@ jobs: - uses: pypa/gh-action-pypi-publish@81e9d935c883d0b210363ab89cf05f3894778450 # v1.8.14 with: packages-dir: artifact/ - - publish-pypi-too: - needs: [ provenance ] - # Wait for approval before attempting to upload to PyPI. This allows reviewing the - # files in the draft release. - environment: - name: publish - url: https://pypi.org/project/Flask-Security-Too/${{ github.ref_name }} - runs-on: ubuntu-latest - permissions: - id-token: write - steps: - - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 - - uses: pypa/gh-action-pypi-publish@81e9d935c883d0b210363ab89cf05f3894778450 # v1.8.14 - with: - packages-dir: artifact/ diff --git a/LICENSE b/LICENSE.txt similarity index 100% rename from LICENSE rename to LICENSE.txt diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index be5a7d0a..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,24 +0,0 @@ -include .editorconfig -include AUTHORS -include CHANGES.rst -include CONTRIBUTING.rst -include LICENSE -include README.rst -include babel.ini -include pytest.ini -include tox.ini -include requirements/*.txt -include flask_security/py.typed -graft examples -graft docs -graft flask_security/templates -graft flask_security/translations -graft flask_security/static -graft tests -prune tests/.pytest_cache -prune tests/.DS_Store -recursive-exclude tests/.pytest_cache * -exclude .coverage tests/.coverage -prune docs/_build -prune scripts -global-exclude *.pyc diff --git a/pyproject-too.toml b/pyproject-too.toml new file mode 100644 index 00000000..e92715e1 --- /dev/null +++ b/pyproject-too.toml @@ -0,0 +1,124 @@ +[project] +name = "Flask-Security-Too" +description = "Quickly add security features to your Flask application." +readme.content-type = "text/x-rst" +readme.file = "README.rst" +keywords = ["flask security"] +license = { file = "LICENSE.txt" } +maintainers = [{ name = "Chris Wagner", email = "jwag.wagner+github@gmail.com"}] +authors = [{ name = "Matt Wright"}, { name = "Chris Wagner", email = "jwag.wagner+github@gmail.com"}] +requires-python = ">=3.9" +urls.Documentation = "https://flask-security.readthedocs.io" +urls.Homepage = "https://github.com/pallets-eco/flask-security" +urls.Source = "https://github.com/pallets-eco/flask-security" +urls.Tracker = "https://github.com/pallets-eco/flask-security/issues" +urls.Releases = "https://pypi.org/project/Flask-Security/" +classifiers=[ + "Environment :: Web Environment", + "Framework :: Flask", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Topic :: Internet :: WWW/HTTP :: Dynamic Content", + "Topic :: Software Development :: Libraries :: Python Modules", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Development Status :: 5 - Production/Stable", +] +dynamic = [ + "version", +] +dependencies = [ + # flask dependencies include werkzeug, jinja2, itsdangerous, click, blinker + "Flask>=3.0.0", + "Flask-Login>=0.6.3", + "Flask-Principal>=0.4.0", + "Flask-WTF>=1.1.2", + "email-validator>=2.0.0", + "markupsafe>=2.1.0", + "passlib>=1.7.4", + "wtforms>=3.0.0", # for form-level errors + "importlib_resources>=5.10.0", +] + +[project.optional-dependencies] +babel = ["babel>=2.12.1", "flask_babel>=3.1.0"] +fsqla = ["flask_sqlalchemy>=3.1.0", "sqlalchemy>=2.0.18", "sqlalchemy-utils>=0.41.1"] +common = ["argon2_cffi>=21.3.0", "bcrypt>=4.0.1", "flask_mailman>=0.3.0", "bleach>=6.0.0"] +mfa = ["cryptography>=40.0.2", "qrcode>=7.4.2", "phonenumberslite>=8.13.11", "webauthn>=2.0.0"] +low = [ + # Lowest supported versions + "Flask==3.0.0", + "Flask-SQLAlchemy==3.1.0", + "Flask-SQLAlchemy-Lite==0.1.0;python_version>='3.10'", + "Flask-Babel==3.1.0", + "Flask-Mailman==0.3.0", + "Flask-Login==0.6.3", + "Flask-WTF==1.1.2", + "peewee==3.16.2", + "argon2_cffi==21.3.0", + "authlib==1.2.0", + "babel==2.12.1", + "bcrypt==4.0.1", + "bleach==6.0.0", + "freezegun", + "jinja2==3.1.2", + "itsdangerous==2.1.2", + "markupsafe==2.1.2", + "mongoengine==0.27.0", + "mongomock==4.1.2", + "pony==0.7.16;python_version<'3.11'", + "phonenumberslite==8.13.11", + "qrcode==7.4.2", + # authlib requires requests + "requests", + # passlib required setuptools + "setuptools", + "sqlalchemy==2.0.18", + "sqlalchemy-utils==0.41.1", + "webauthn==2.0.0", + "werkzeug==3.0.1", + "zxcvbn==4.4.28" +] +[build-system] +requires = ["flit_core >=3.8,<4"] +build-backend = "flit_core.buildapi" + +[tool.flit.module] +name = "flask_security" + +[tool.flit.sdist] +include = [ + "AUTHORS", + "CHANGES.rst", + "CONTRIBUTING.rst", + "LICENSE.txt", + ".djlintrc", + ".git-blame-ignore-revs", + ".gitignore", + ".pre-commit-config.yaml", + "babel.ini", + "codecov.yml", + "mypy.ini", + "pytest.ini", + "tox.ini", + "docs/", + "examples/", + "requirements", + "tests/", +] +exclude = ["docs/_build/"] + +[tool.djlint] + ignore="H005,H006" # lang, img height/width + +[tool.pyright] + include=["flask_security", "tests/view_scaffold.py"] + analyzeUnannotatedFunctions = "none" + reportMissingImports = false diff --git a/pyproject.toml b/pyproject.toml index 89353093..6101752d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,14 +1,10 @@ -[build-system] -requires = ["setuptools"] -build-backend = "setuptools.build_meta" - [project] name = "Flask-Security" description = "Quickly add security features to your Flask application." readme.content-type = "text/x-rst" readme.file = "README.rst" keywords = ["flask security"] -# license = "MIT" +license = { file = "LICENSE.txt" } maintainers = [{ name = "Chris Wagner", email = "jwag.wagner+github@gmail.com"}] authors = [{ name = "Matt Wright"}, { name = "Chris Wagner", email = "jwag.wagner+github@gmail.com"}] requires-python = ">=3.9" @@ -90,9 +86,34 @@ low = [ "werkzeug==3.0.1", "zxcvbn==4.4.28" ] +[build-system] +requires = ["flit_core >=3.8,<4"] +build-backend = "flit_core.buildapi" -[tool.setuptools.dynamic] -version = {attr = "flask_security.__version__"} +[tool.flit.module] +name = "flask_security" + +[tool.flit.sdist] +include = [ + "AUTHORS", + "CHANGES.rst", + "CONTRIBUTING.rst", + "LICENSE.txt", + ".djlintrc", + ".git-blame-ignore-revs", + ".gitignore", + ".pre-commit-config.yaml", + "babel.ini", + "codecov.yml", + "mypy.ini", + "pytest.ini", + "tox.ini", + "docs/", + "examples/", + "requirements", + "tests/", +] +exclude = ["docs/_build/"] [tool.djlint] ignore="H005,H006" # lang, img height/width diff --git a/requirements/dev.txt b/requirements/dev.txt index d935a3d6..f32d6e83 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,7 +1,7 @@ -r docs.txt -r tests.txt mypy -build +flit check-wheel-contents psycopg2-binary pymysql diff --git a/tox.ini b/tox.ini index b56f32ba..e45b6634 100644 --- a/tox.ini +++ b/tox.ini @@ -124,13 +124,23 @@ commands = [testenv:makedist] deps = -r requirements/tests.txt - build - setuptools + flit twine check-wheel-contents commands = tox -e compile_catalog - python -m build + flit build --no-use-vcs + check-wheel-contents dist + +[testenv:makedist-too] +deps = + -r requirements/tests.txt + flit + twine + check-wheel-contents +commands = + tox -e compile_catalog + flit -f pyproject-too.toml build --no-use-vcs check-wheel-contents dist [testenv:mypy]