diff --git a/.cirrus.yml b/.cirrus.yml index c54ff6e7656..8095910b231 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -41,7 +41,6 @@ tests_task: - echo "PATH=${POETRY_HOME}/bin:${PATH}" >> $CIRRUS_ENV setup_environment_script: - # FIXME: --sync is broken due to a bug with py-sqlite3 packaging. # TODO: caching - poetry install - poetry env info diff --git a/.github/actions/bootstrap-poetry/action.yml b/.github/actions/bootstrap-poetry/action.yml index ad8ec7d6b2a..5a8a8013dd5 100644 --- a/.github/actions/bootstrap-poetry/action.yml +++ b/.github/actions/bootstrap-poetry/action.yml @@ -3,29 +3,42 @@ description: Configure the environment with the specified Python and Poetry vers inputs: python-version: - description: Desired Python version - default: "3.12" + description: Desired Python version expression + default: '3.12' python-latest: description: Use an uncached Python if a newer match is available default: 'false' + python-prereleases: + description: Allow usage of pre-release Python versions + default: 'false' poetry-spec: description: pip-compatible installation specification to use for Poetry default: 'poetry' +outputs: + python-path: + description: Path to the installed Python interpreter + value: ${{ steps.setup-python.outputs.python-path }} + python-version: + description: Version of the installed Python interpreter + value: ${{ steps.setup-python.outputs.python-version }} + runs: using: composite steps: + - uses: actions/setup-python@v5 + id: setup-python + with: + python-version: ${{ inputs.python-version }} + check-latest: ${{ inputs.python-latest == 'true' }} + allow-prereleases: ${{ inputs.python-prereleases == 'true' }} + update-environment: false + + - run: pipx install --python '${{ steps.setup-python.outputs.python-path }}' '${{ inputs.poetry-spec }}' + shell: bash + # Enable handling long path names (+260 char) on the Windows platform # https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#maximum-path-length-limitation - run: git config --system core.longpaths true if: runner.os == 'Windows' shell: pwsh - - - run: pipx install '${{ inputs.poetry-spec }}' - shell: bash - - - uses: actions/setup-python@v5 - with: - python-version: ${{ inputs.python-version }} - check-latest: ${{ inputs.python-latest == 'true' }} - cache: poetry diff --git a/.github/actions/poetry-install/action.yml b/.github/actions/poetry-install/action.yml new file mode 100644 index 00000000000..bc0c03f7123 --- /dev/null +++ b/.github/actions/poetry-install/action.yml @@ -0,0 +1,50 @@ +name: Poetry Install +description: Run `poetry install` with optional artifact and metadata caching + +inputs: + args: + description: Arguments for `poetry install` + cache: + description: Enable transparent Poetry artifact and metadata caching + default: 'true' + +outputs: + cache-hit: + description: Whether an exact cache hit occured + value: ${{ steps.cache.outputs.cache-hit }} + +runs: + using: composite + steps: + - run: printf 'cache-dir=%s\n' "$(poetry config cache-dir)" >> $GITHUB_OUTPUT + id: poetry-config + shell: bash + + # Bust the cache every 24 hours to prevent it from expanding over time. + - run: printf 'date=%s\n' "$(date -I)" >> $GITHUB_OUTPUT + id: get-date + if: inputs.cache == 'true' + shell: bash + + - uses: actions/cache@v4 + id: cache + if: inputs.cache == 'true' + with: + path: | + ${{ steps.poetry-config.outputs.cache-dir }}/artifacts + ${{ steps.poetry-config.outputs.cache-dir }}/cache + key: poetry-${{ steps.get-date.outputs.date }}-${{ runner.os }}-${{ hashFiles('pyproject.toml', 'poetry.lock') }} + # The cache is cross-platform, and other platforms are used to seed cache misses. + restore-keys: | + poetry-${{ steps.get-date.outputs.date }}-${{ runner.os }}- + poetry-${{ steps.get-date.outputs.date }}- + enableCrossOsArchive: true + + - run: poetry install ${{ inputs.args }} + shell: bash + + - run: poetry env info + shell: bash + + - run: poetry show + shell: bash diff --git a/.github/workflows/.tests-matrix.yaml b/.github/workflows/.tests-matrix.yaml index 661097db8ba..f2d931d47b5 100644 --- a/.github/workflows/.tests-matrix.yaml +++ b/.github/workflows/.tests-matrix.yaml @@ -31,21 +31,18 @@ jobs: - uses: actions/checkout@v4 - uses: ./.github/actions/bootstrap-poetry + id: bootstrap-poetry with: python-version: ${{ inputs.python-version }} - - run: poetry install --sync - - - run: poetry env info - - - run: poetry show + - uses: ./.github/actions/poetry-install - uses: actions/cache@v4 with: path: .mypy_cache - key: mypy-${{ runner.os }}-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'poetry.lock') }} + key: mypy-${{ runner.os }}-py${{ steps.bootstrap-poetry.outputs.python-version }}-${{ hashFiles('pyproject.toml', 'poetry.lock') }} restore-keys: | - mypy-${{ runner.os }}-${{ env.pythonLocation }}- + mypy-${{ runner.os }}-py${{ steps.bootstrap-poetry.outputs.python-version }}- mypy-${{ runner.os }}- - run: poetry run mypy @@ -61,11 +58,9 @@ jobs: with: python-version: ${{ inputs.python-version }} - - run: poetry install --sync --with github-actions - - - run: poetry env info - - - run: poetry show + - uses: ./.github/actions/poetry-install + with: + args: --with github-actions - run: poetry run pytest --integration -v env: @@ -85,11 +80,9 @@ jobs: with: python-version: ${{ inputs.python-version }} - - run: poetry install --sync --with github-actions - - - run: poetry env info - - - run: poetry show + - uses: ./.github/actions/poetry-install + with: + args: --with github-actions - run: poetry run pip list --format json | jq -r '.[] | "\(.name)=\(.version)"' >> $GITHUB_OUTPUT id: package-versions diff --git a/.github/workflows/backport.yaml b/.github/workflows/backport.yaml index aca765d1b91..e7f8faa0186 100644 --- a/.github/workflows/backport.yaml +++ b/.github/workflows/backport.yaml @@ -28,13 +28,13 @@ jobs: with: app-id: ${{ secrets.POETRY_TOKEN_APP_ID }} private-key: ${{ secrets.POETRY_TOKEN_APP_KEY }} - - run: | + - name: backport.sh + run: | git config --global user.name "${{ steps.app-token.outputs.slug }}[bot]" git config --global user.email "${{ steps.app-token.outputs.slug }}[bot]@users.noreply.github.com" gh repo fork --remote-name fork ./.github/scripts/backport.sh --pr ${{ github.event.pull_request.number }} --comment --remote fork - name: backport.sh env: GH_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 86b8fe6cfeb..a11465733c4 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -46,9 +46,12 @@ jobs: - uses: ./.github/actions/bootstrap-poetry - - run: poetry install --sync --no-root --only main + - uses: ./.github/actions/poetry-install + with: + args: --no-root --only main - - run: | + - name: website-build + run: | # Rebuild the docs files from the PR checkout. poetry run python bin/website build --local ./poetry # Build website assets (CSS/JS). diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 49c8d951b84..891657f2162 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -35,7 +35,9 @@ jobs: upload-pypi: name: Upload (PyPI) runs-on: ubuntu-latest - environment: pypi + environment: + name: pypi + url: https://pypi.org/project/poetry/ permissions: id-token: write needs: build diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 128290183d9..4b755ba024d 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -20,9 +20,8 @@ jobs: outputs: project: ${{ steps.changes.outputs.project }} fixtures-pypi: ${{ steps.changes.outputs.fixtures-pypi }} - mypy: ${{ steps.changes.outputs.mypy }} - pytest: ${{ steps.changes.outputs.pytest }} - pytest-export: ${{ steps.changes.outputs.pytest-export }} + src: ${{ steps.changes.outputs.src }} + tests: ${{ steps.changes.outputs.tests }} steps: - uses: actions/checkout@v4 - uses: dorny/paths-filter@v3 @@ -39,16 +38,13 @@ jobs: fixtures-pypi: - *workflow - 'tests/repositories/fixtures/pypi.org/**' - mypy: + src: - *project - 'src/**.py' - pytest: + tests: - *project - 'src/**.py' - 'tests/**' - pytest-export: - - *project - - 'src/**.py' lockfile: name: Check poetry.lock @@ -62,6 +58,25 @@ jobs: - run: poetry check --lock + smoke: + name: Smoke-test build and install + runs-on: ubuntu-latest + if: needs.changes.outputs.project == 'true' + needs: lockfile + steps: + - uses: actions/checkout@v4 + + - run: pipx run build + + - run: pipx run twine check --strict dist/* + + - run: pipx install --suffix=@build dist/*.whl + + - uses: ./.github/actions/bootstrap-poetry + + # Smoke test: confirm the version of the installed wheel matches the project. + - run: poetry@build --version | grep $(poetry version --short) + fixtures-pypi: name: Check fixtures (PyPI) runs-on: ubuntu-latest @@ -72,7 +87,9 @@ jobs: - uses: ./.github/actions/bootstrap-poetry - - run: poetry install --sync --only main,test + - uses: ./.github/actions/poetry-install + with: + args: --only main,test - run: poetry run env PYTHONPATH="$GITHUB_WORKSPACE" python tests/repositories/fixtures/pypi.org/generate.py @@ -99,9 +116,9 @@ jobs: with: runner: ${{ matrix.os.image }} python-version: ${{ matrix.python-version }} - run-mypy: ${{ needs.changes.outputs.mypy == 'true' }} - run-pytest: ${{ needs.changes.outputs.pytest == 'true' }} - run-pytest-export: ${{ needs.changes.outputs.pytest-export == 'true' }} + run-mypy: ${{ needs.changes.outputs.src == 'true' }} + run-pytest: ${{ needs.changes.outputs.tests == 'true' }} + run-pytest-export: ${{ needs.changes.outputs.src == 'true' }} secrets: inherit status: @@ -110,6 +127,7 @@ jobs: if: always() needs: - lockfile + - smoke - fixtures-pypi - tests-matrix steps: