diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 83f04ed..40ca50a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,9 +32,37 @@ on: jobs: + get-changed-files: + name: Get Changed Files + runs-on: ubuntu-latest + permissions: + contents: read # for dorny/paths-filter to fetch a list of changed files + pull-requests: read # for dorny/paths-filter to read pull requests + outputs: + changed-files: ${{ toJSON(steps.changed-files.outputs) }} + steps: + - uses: actions/checkout@v3 + - name: Get Changed Files + id: changed-files + uses: dorny/paths-filter@v2 + with: + token: ${{ github.token }} + list-files: json + filters: | + repo: + - added|modified: + - '**' + deleted: + - deleted: + - '**' + pre-commit: name: Pre-Commit uses: ./.github/workflows/pre-commit-action.yml + needs: + - get-changed-files + with: + changed-files: ${{ needs.get-changed-files.outputs.changed-files }} build-python-package: name: Python Package @@ -44,5 +72,72 @@ jobs: - pre-commit with: kind: "${{ inputs.kind }}" - cmd: "${{ inputs.package_command }}" + cmd: python -m build + #cmd: "${{ inputs.package_command }}" + + test: + name: Test + needs: + - get-changed-files + uses: ./.github/workflows/test-action.yml + with: + changed-files: ${{ needs.get-changed-files.outputs.changed-files }} + + deploy-python-package: + name: Deploy Python Package + uses: ./.github/workflows/deploy-package-action.yml + if: ${{ inputs.kind == 'release' && success() }} + needs: + - pre-commit + - test + - build-python-package + secrets: + PYPI_API_TOKEN: "${{ secrets.PYPI_API_TOKEN }}" + + push-tag: + name: Push Version Tag + runs-on: ubuntu-latest + permissions: + contents: write + if: ${{ inputs.kind == 'release' && success() }} + needs: + - build-python-package + - deploy-python-package + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Push Tag + uses: rickstaa/action-create-tag@v1 + with: + tag: "v${{ needs.build-python-package.outputs.version }}" + message: "Version ${{ needs.build-python-package.outputs.version }}" + + set-pipeline-exit-status: + # This step is just so we can make github require this step, to pass checks + # on a pull request instead of requiring all + name: Set the CI Pipeline Exit Status + runs-on: ubuntu-latest + if: always() + needs: + - pre-commit + - test + - deploy-python-package + - push-tag + steps: + - name: Get workflow information + id: get-workflow-info + uses: technote-space/workflow-conclusion-action@v3 + + - name: Set Pipeline Exit Status + shell: bash + run: | + if [ "${{ steps.get-workflow-info.outputs.conclusion }}" != "success" ]; then + exit 1 + else + exit 0 + fi + - name: Done + if: always() + run: + echo "All workflows finished" diff --git a/.github/workflows/deploy-package-action.yml b/.github/workflows/deploy-package-action.yml new file mode 100644 index 0000000..27605e1 --- /dev/null +++ b/.github/workflows/deploy-package-action.yml @@ -0,0 +1,22 @@ +name: Relenv Python Package + +on: + workflow_call: + secrets: + PYPI_API_TOKEN: + required: true + +jobs: + build: + name: Publish Python Wheel + runs-on: ubuntu-latest + steps: + - name: Download Python Package Artifacts + uses: actions/download-artifact@v3 + with: + name: dist + path: dist + - name: Publish distribution to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/package-action.yml b/.github/workflows/package-action.yml index 729a025..ff217e1 100644 --- a/.github/workflows/package-action.yml +++ b/.github/workflows/package-action.yml @@ -25,80 +25,62 @@ on: jobs: build: name: Build Python Wheel - strategy: - matrix: - host: - - x86_64 - - aarch64 - runs-on: - - self-hosted - - linux - - src-build - - ${{ matrix.host }} + runs-on: ubuntu-latest + container: + image: debian:11 outputs: version: ${{ steps.version.outputs.version }} - steps: - - uses: actions/checkout@master + - uses: actions/checkout@master -# - name: Set up Python 3.10 -# uses: actions/setup-python@v4 -# with: -# python-version: "3.10" + - name: Update Apt + run: >- + apt-get update - - name: Install pypa/build - run: >- - python -m - pip install - build - --user + - name: Install OS Dependencies + run: >- + apt-get install -y gcc python3 + python3-pip python3-venv flex make + texinfo unzip help2man gawk libtool-bin libncurses5-dev + bison wget rsync git - - name: Install pypa/pkginffo - run: >- - python -m - pip install - pkginfo - --user + - name: Create virtualenv + run: >- + python3 -m venv venv - - name: Install relenv - run: >- - python -m - pip install - relenv - --user + - name: Activate virtualenv + run: | + . venv/bin/activate + echo PATH=$PATH >> $GITHUB_ENV - - name: Install relenv toolchain - run: >- - python -m - relenv - toolchain - fetch + - name: Python Version + run: >- + python3 --version - - name: Install relenv fetch - run: >- - python -m - relenv - fetch + - name: Install Python Dependencies + run: >- + pip install build wheel setuptools pkginfo - - name: Echo Build Wheel Command - run: echo "${{ inputs.cmd }}" + - name: Echo Build Wheel Command + run: echo "${{ inputs.cmd }}" - - name: Build Wheel - run: "${{ inputs.cmd }}" + - name: Build Wheel + run: | + ${{ inputs.cmd }} - - name: Wheel Artifact ${{matrix.host}} - uses: actions/upload-artifact@v3 - if: always() - with: - name: relenv-gdb-debug-${{ matrix.host }}-wheel - path: dist/*.whl - retention-days: 5 + - name: Python Build Artifact + uses: actions/upload-artifact@v3 + if: always() + with: + name: dist + path: dist/* + retention-days: 5 - - name: Read Version - run: >- - python3 - -c - "from pkginfo import Wheel; s = Wheel('dist/$(ls dist/)'); print(f'version={s.version}')" - >> - $GITHUB_OUTPUT - id: version + - name: Read Version + run: >- + python3 + -c + "from pkginfo import Wheel; s = Wheel('''$(ls dist/*.whl)'''); print('version='+str(s.version))" + >> + $GITHUB_OUTPUT + id: version diff --git a/.github/workflows/pre-commit-action.yml b/.github/workflows/pre-commit-action.yml index 86324c1..12d334b 100644 --- a/.github/workflows/pre-commit-action.yml +++ b/.github/workflows/pre-commit-action.yml @@ -4,7 +4,7 @@ on: workflow_call: inputs: changed-files: - required: false + required: true type: string description: JSON string containing information about changed files @@ -30,5 +30,11 @@ jobs: pre-commit install --install-hooks - name: Check ALL Files On Branch + if: github.event_name != 'pull_request' run: | pre-commit run --show-diff-on-failure --color=always --all-files + + - name: Check Changed Files On PR + if: github.event_name == 'pull_request' && fromJSON(inputs.changed-files)['repo'] == 'true' + run: | + pre-commit run --show-diff-on-failure --color=always --files ${{ join(fromJSON(inputs.changed-files)['repo_files'], ' ') }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..5c458a7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,32 @@ +name: Build and Release + +on: + workflow_dispatch: + inputs: + kind: + required: false + type: string + default: dev + package_command: + required: false + type: string + description: Command used to build python package + default: >- + python -m + build + --wheel + --outdir dist/ + +jobs: + ci: + name: CI + permissions: + contents: write + pull-requests: read + uses: ./.github/workflows/ci.yml + if: contains('["dwoz", "twangboy", "dmurphy18"]', github.actor) + with: + kind: "${{ inputs.kind }}" + package_command: "${{ inputs.package_command }}" + secrets: + PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/test-action.yml b/.github/workflows/test-action.yml new file mode 100644 index 0000000..e88027a --- /dev/null +++ b/.github/workflows/test-action.yml @@ -0,0 +1,39 @@ +name: Unit Tests + +on: + workflow_call: + inputs: + changed-files: + required: true + type: string + description: JSON string containing information about changed files + +jobs: + test: + strategy: + fail-fast: false + matrix: + runs-on: + - ubuntu-latest + - macos-12 + - macos-13-xlarge + - windows-latest + + name: Unit Test ${{ matrix.runs-on }} + runs-on: ${{ matrix.runs-on }} + + steps: + - uses: actions/checkout@v3 + + - name: Set up Python 3.10 + uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Install python dependencies + run: | + pip3 install pytest + + - name: Run tests + run: | + pytest -v diff --git a/pyproject.toml b/pyproject.toml index 132b443..eae03cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ requires = [ "setuptools", "wheel", - "relenv@git+https://github.com/saltstack/relative-environment-for-python@buildenv", + "relenv", ] build-backend = "build" backend-path = ["src/relenv_gdb"] diff --git a/src/relenv_gdb/build.py b/src/relenv_gdb/build.py index bee6c4b..1ec06c5 100644 --- a/src/relenv_gdb/build.py +++ b/src/relenv_gdb/build.py @@ -10,10 +10,14 @@ import shutil import subprocess import tempfile +import pprint import relenv.buildenv import relenv.common import relenv.create +import relenv.build +import relenv.fetch +import relenv.toolchain from setuptools.build_meta import * _build_wheel = build_wheel @@ -53,9 +57,8 @@ def build_gdb(prefix): os.environ[ "CPPFLAGS" ] = f"{os.environ['CPPFLAGS']} -I{os.environ['RELENV_PATH']}/include/ncursesw" - import pprint - pprint.pprint(dict(os.environ)) + print(f"Build environment: {pprint.pformat(dict(os.environ))}") with pushd(src / dir_name): subprocess.run( @@ -116,8 +119,24 @@ def build_wheel(wheel_directory, metadata_directory=None, config_settings=None): # relenv.common.get_triplet(relenv.common.build_arch()), # ) static_build_dir = os.environ.get("PY_STATIC_BUILD_DIR", "") + + #XXX should be in relenv + dirs = relenv.common.work_dirs() + if not dirs.toolchain.exists(): + os.makedirs(dirs.toolchain) + if not dirs.build.exists(): + os.makedirs(dirs.build) + + arch = relenv.common.build_arch() + triplet = relenv.common.get_triplet(machine=arch) + python = relenv.build.platform_versions()[0] + if static_build_dir: relenvdir = (pathlib.Path(static_build_dir) / "gdb").resolve() + relenv.toolchain.fetch( + arch, dirs.toolchain + ) + relenv.fetch.fetch(relenv.common.__version__, triplet, python) relenv.create.create(str(relenvdir)) build_gdb(relenvdir) try: @@ -127,6 +146,10 @@ def build_wheel(wheel_directory, metadata_directory=None, config_settings=None): else: with tempfile.TemporaryDirectory() as tmp_dist_dir: relenvdir = pathlib.Path(tmp_dist_dir) / "gdb" + relenv.toolchain.fetch( + arch, dirs.toolchain + ) + relenv.fetch.fetch(relenv.common.__version__, triplet, python) relenv.create.create(str(relenvdir)) build_gdb(relenvdir) try: