diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1f6bbe234..6f5cb1659 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -67,7 +67,7 @@ jobs: needs: build-docstrings strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-14] + os: [ubuntu-latest, windows-2022, macos-14] runs-on: ${{ matrix.os }} steps: - name: Print home directory @@ -78,13 +78,13 @@ jobs: with: cmake-version: '3.29.x' - name: Cache .hunter folder - if: matrix.os != 'windows-latest' + if: matrix.os != 'windows-2022' uses: actions/cache@v4 with: path: ~/.hunter/ key: hunter-pytest-${{ matrix.os }} - name: Cache .hunter folder - if: matrix.os == 'windows-latest' + if: matrix.os == 'windows-2022' uses: actions/cache@v4 with: path: C:/.hunter/ @@ -136,7 +136,11 @@ jobs: needs: build-docstrings strategy: matrix: - rpi-os: [rpi-bullseye, rpi-bookworm] + include: + - rpi-os: rpi-bullseye + auditwheel-plat: manylinux_2_31_armv7l + - rpi-os: rpi-bookworm + auditwheel-plat: manylinux_2_36_armv7l runs-on: ${{ matrix.rpi-os }} steps: - name: Print home directory @@ -160,7 +164,7 @@ jobs: - name: Auditing wheels and adding armv6l tag (Running on RPi, binaries compiled as armv6l) run: | # python3 -m pip install -U wheel auditwheel # Called once when setting up the runner - for whl in wheelhouse/*.whl; do auditwheel repair "$whl" --plat linux_armv7l -w wheelhouse/preaudited/; done + for whl in wheelhouse/*.whl; do auditwheel repair "$whl" --plat ${{ matrix.auditwheel-plat }} -w wheelhouse/preaudited/; done for whl in wheelhouse/preaudited/*.whl; do python3 -m wheel tags --platform-tag +linux_armv6l "$whl"; done mkdir -p wheelhouse/audited/ for whl in wheelhouse/preaudited/*linux_armv6l*.whl; do cp "$whl" wheelhouse/audited/$(basename $whl); done @@ -169,19 +173,10 @@ jobs: with: name: audited-wheels-${{ matrix.rpi-os }} path: wheelhouse/audited/ - - name: Deploy wheels to artifactory (if not a release) - if: startsWith(github.ref, 'refs/tags/v') != true - run: bash ./ci/upload-artifactory.sh - env: - ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }} - ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} - ARTIFACTORY_PASS: ${{ secrets.ARTIFACTORY_PASS }} - - # This job builds wheels for Windows x86_64 arch build-windows-x86_64: needs: build-docstrings - runs-on: windows-latest + runs-on: windows-2022 strategy: matrix: python-version: [3.9, '3.10', '3.11', '3.12', '3.13', '3.14'] @@ -232,14 +227,6 @@ jobs: with: name: audited-wheels-windows-${{ matrix.python-version }}-${{ matrix.python-architecture }} path: wheelhouse/audited/ - - name: Deploy wheels to artifactory (if not a release) - if: startsWith(github.ref, 'refs/tags/v') != true - run: bash ./ci/upload-artifactory.sh - env: - ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }} - ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} - ARTIFACTORY_PASS: ${{ secrets.ARTIFACTORY_PASS }} - # This job builds wheels for macOS x86_64 arch build-macos: needs: build-docstrings @@ -293,14 +280,6 @@ jobs: with: name: audited-wheels-macos-${{ matrix.python-version }}-${{ matrix.os }} path: wheelhouse/audited/ - - name: Deploy wheels to artifactory (if not a release) - if: startsWith(github.ref, 'refs/tags/v') != true - run: bash ./ci/upload-artifactory.sh - env: - ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }} - ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} - ARTIFACTORY_PASS: ${{ secrets.ARTIFACTORY_PASS }} - # This job builds wheels for x86_64 arch build-linux-x86_64: needs: build-docstrings @@ -358,14 +337,6 @@ jobs: with: name: audited-wheels-linux-x86_64 path: wheelhouse/audited/ - - name: Deploy wheels to artifactory (if not a release) - if: startsWith(github.ref, 'refs/tags/v') != true - run: bash ./ci/upload-artifactory.sh - env: - ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }} - ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} - ARTIFACTORY_PASS: ${{ secrets.ARTIFACTORY_PASS }} - # This job builds wheels for ARM64 arch build-linux-arm64: needs: build-docstrings @@ -415,13 +386,24 @@ jobs: with: name: audited-wheels-linux-arm64 path: wheelhouse/audited/ - - name: Deploy wheels to artifactory (if not a release) - if: startsWith(github.ref, 'refs/tags/v') != true - run: bash ./ci/upload-artifactory.sh + upload-wheels-to-ak: + if: (github.event_name == 'workflow_dispatch' || github.event_name == 'push') && !startsWith(github.ref, 'refs/tags/v') + needs: [build-linux-armhf, build-windows-x86_64, build-macos, build-linux-x86_64, build-linux-arm64] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: 'recursive' + - uses: actions/download-artifact@v4 + with: + pattern: audited-wheels* + merge-multiple: true + path: wheelhouse/audited/ + - name: Upload wheels to Artifact Keeper + run: bash ./ci/upload-ak.sh --snapshot env: - ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }} - ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} - ARTIFACTORY_PASS: ${{ secrets.ARTIFACTORY_PASS }} + AK_URL: ${{ secrets.AK_URL }} + AK_TOKEN: ${{ secrets.AK_TOKEN }} release: if: startsWith(github.ref, 'refs/tags/v') @@ -458,7 +440,7 @@ jobs: draft: true - # Deploy to PyPi and Artifactory. Only when a commit is tagged + # Deploy to PyPi and Artifact Keeper. Only when a commit is tagged deploy: if: startsWith(github.ref, 'refs/tags/v') needs: [release] @@ -480,12 +462,11 @@ jobs: PYPI_SERVER: ${{ secrets.PYPI_SERVER }} PYPI_USER: ${{ secrets.PYPI_USER }} PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - - name: Run deploy to Artifactory - run: bash ./ci/upload-artifactory-release.sh + - name: Run deploy to Artifact Keeper + run: bash ./ci/upload-ak.sh --release env: - ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }} - ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} - ARTIFACTORY_PASS: ${{ secrets.ARTIFACTORY_PASS }} + AK_URL: ${{ secrets.AK_URL }} + AK_TOKEN: ${{ secrets.AK_TOKEN }} # notify_hil_workflow_linux_x86_64: diff --git a/ci/upload-ak.sh b/ci/upload-ak.sh new file mode 100755 index 000000000..933067239 --- /dev/null +++ b/ci/upload-ak.sh @@ -0,0 +1,55 @@ +#!/bin/bash +set -euo pipefail + +: "${AK_URL:?AK_URL must be set}" +: "${AK_TOKEN:?AK_TOKEN must be set}" + +case "$1" in + --snapshot) + AK_REPO="luxonis-python-snapshot-local" + ;; + --release) + AK_REPO="luxonis-python-release-local" + ;; + *) + echo "Error: Unknown option $1" + echo "Usage: $0 [--snapshot | --release]" + exit 1 + ;; +esac + +AK_BASE_URL="${AK_URL%/}" +AK_PYPI_REPOSITORY_URL="${AK_BASE_URL}/pypi/${AK_REPO}/" +AK_PYPI_SIMPLE_URL="${AK_BASE_URL}/pypi/${AK_REPO}/simple/depthai/" + +python3 -m pip install -U pip +python3 -m pip install -U twine +python3 -m pip install -U packaging + +shopt -s nullglob +wheels=(wheelhouse/audited/*.whl) +if [ "${#wheels[@]}" -eq 0 ]; then + echo "No wheels found in wheelhouse/audited/" + exit 1 +fi + +for wheel in "${wheels[@]}"; do + echo "Uploading ${wheel}" + python3 -m twine upload \ + --repository-url "${AK_PYPI_REPOSITORY_URL}" \ + --username "__token__" \ + --password "${AK_TOKEN}" \ + "${wheel}" +done + +index_html="$(mktemp)" +trap 'rm -f "${index_html}"' EXIT +curl -fsSL "${AK_PYPI_SIMPLE_URL}" -o "${index_html}" + +for wheel in "${wheels[@]}"; do + wheel_name="$(basename "${wheel}")" + if ! grep -Fq "${wheel_name}" "${index_html}"; then + echo "Uploaded wheel is missing from the PyPI simple index: ${wheel_name}" + exit 1 + fi +done diff --git a/ci/upload-artifactory-release.sh b/ci/upload-artifactory-release.sh deleted file mode 100755 index 6669bcace..000000000 --- a/ci/upload-artifactory-release.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -curl -fL https://getcli.jfrog.io | sh - -cd wheelhouse/audited/ || exit 1 -export PATH_PREFIX=luxonis-python-release-local/depthai - -../../jfrog config add --artifactory-url=$ARTIFACTORY_URL --user=$ARTIFACTORY_USER --password=$ARTIFACTORY_PASS -../../jfrog rt u "*" "$PATH_PREFIX/" diff --git a/ci/upload-artifactory.sh b/ci/upload-artifactory.sh deleted file mode 100755 index b00b77323..000000000 --- a/ci/upload-artifactory.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -curl -fL https://getcli.jfrog.io | sh - -cd wheelhouse/audited/ || exit 1 -export PATH_PREFIX=luxonis-python-snapshot-local/depthai - -../../jfrog config add --artifactory-url=$ARTIFACTORY_URL --user=$ARTIFACTORY_USER --password=$ARTIFACTORY_PASS -../../jfrog rt u "*" "$PATH_PREFIX/"