diff --git a/.github/workflows/pr-nuget-packaging.yml b/.github/workflows/pr-nuget-packaging.yml new file mode 100644 index 000000000..29f1bac31 --- /dev/null +++ b/.github/workflows/pr-nuget-packaging.yml @@ -0,0 +1,150 @@ +name: "Pull Request NuGet Packaging" + +on: + workflow_run: + workflows: + - Pull Request Test + types: + - completed + +concurrency: + group: ${{ github.workflow }}-${{ github.event.workflow_run.id }} + cancel-in-progress: false + +defaults: + run: + shell: bash --noprofile --norc -euo pipefail {0} + +env: + USERNAME: ${{ github.repository_owner }} + FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json + VCPKG_BINARY_SOURCES: "clear;nuget,https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json,readwrite" + VCPKG_FEATURE_FLAGS: "manifests,registries,binarycaching" + CMAKE_BUILD_PARALLEL_LEVEL: 4 + CTEST_PARALLEL_LEVEL: 4 + CTEST_OUTPUT_ON_FAILURE: 1 + +jobs: + publish-nuget: + name: Publish NuGet packages (ubuntu-24.04) + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.pull_requests[0].number != null && + github.event.workflow_run.head_repository.full_name == github.repository + runs-on: ubuntu-24.04 + environment: + name: nuget-publish + permissions: + contents: read + packages: write + actions: read + steps: + - name: Checkout pull request merge commit + uses: actions/checkout@v4 + with: + repository: ${{ github.event.workflow_run.repository.full_name }} + ref: ${{ format('refs/pull/{0}/merge', github.event.workflow_run.pull_requests[0].number) }} + fetch-depth: 0 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + cache: 'pip' + cache-dependency-path: | + requirements.txt + **/pyproject.toml + **/requirements*.txt + + - name: Install system dependencies (Linux) + run: | + sudo apt-get update + sudo apt-get install -y \ + ninja-build build-essential \ + pkg-config autoconf automake libtool \ + zip unzip \ + bison swig \ + libdrm-dev \ + libx11-dev libxkbcommon-x11-dev libx11-xcb-dev \ + libxft-dev libxext-dev libgles2-mesa-dev \ + libxi-dev libxtst-dev libxrandr-dev libltdl-dev \ + libgtk2.0-dev \ + python3-setuptools python3-jinja2 python3-tk \ + mono-complete + + - name: Setup CMake 3.28.3 + uses: jwlawson/actions-setup-cmake@v2 + with: + cmake-version: '3.28.3' + + - name: Install vcpkg + uses: lukka/run-vcpkg@v11 + with: + vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg' + vcpkgJsonGlob: "src/vcpkg.json" + vcpkgConfigurationJsonGlob: "src/vcpkg-configuration.json" + + - name: Cache vcpkg build artifacts + uses: actions/cache@v4 + with: + path: | + ${{ runner.workspace }}/b/vcpkg/installed + ${{ runner.workspace }}/b/vcpkg/packages + ${{ runner.workspace }}/b/vcpkg/buildtrees + key: vcpkg-${{ runner.os }}-${{ hashFiles('src/vcpkg.json', 'src/vcpkg-configuration.json') }} + + - name: Add NuGet sources for vcpkg binary cache (portable) + env: + VCPKG_EXE: ${{ runner.workspace }}/b/vcpkg/vcpkg + run: | + set -euo pipefail + NUGET="$(${VCPKG_EXE} fetch nuget | tail -n 1)" + + if [[ "$NUGET" == *.exe ]]; then + NUGET_CMD=(mono "$NUGET") + else + NUGET_CMD=("$NUGET") + fi + + echo "Using NuGet CLI: ${NUGET_CMD[*]}" + + "${NUGET_CMD[@]}" sources add \ + -Source "${FEED_URL}" \ + -StorePasswordInClearText \ + -Name GitHubPackages \ + -UserName "${USERNAME}" \ + -Password "${{ secrets.GH_VCPKG_PACKAGES_TOKEN }}" + + "${NUGET_CMD[@]}" setapikey "${{ secrets.GH_VCPKG_PACKAGES_TOKEN }}" \ + -Source "${FEED_URL}" + + - name: Create virtual environment + run: | + python -m venv .venv + source .venv/bin/activate + python -V + pip -V + + - name: Install required Python dependencies + run: | + source .venv/bin/activate + python -m pip install -r requirements.txt + + - name: Configure (CMake preset) + working-directory: src + run: cmake --preset ci-test + + - name: Build + working-directory: src + run: cmake --build ../build --parallel + + - name: Install Basilisk (editable) + run: | + source .venv/bin/activate + cmake --install build --prefix $(pwd)/dist + python -m pip install -e . + + - name: Run C/C++ tests + working-directory: ./build + run: ctest --output-on-failure diff --git a/.github/workflows/pull-request-target.yml b/.github/workflows/pull-request-target.yml new file mode 100644 index 000000000..ce145a89f --- /dev/null +++ b/.github/workflows/pull-request-target.yml @@ -0,0 +1,201 @@ +name: "Pull Request (Forks, NuGet cache read-only)" + +on: + pull_request_target: + +permissions: + contents: read + packages: read + actions: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash --noprofile --norc -euo pipefail {0} + +env: + FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json + VCPKG_BINARY_SOURCES: "clear;nuget,https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json,read" + VCPKG_FEATURE_FLAGS: "manifests,registries,binarycaching" + CMAKE_BUILD_PARALLEL_LEVEL: 4 + CTEST_PARALLEL_LEVEL: 4 + CTEST_OUTPUT_ON_FAILURE: 1 + +jobs: + pre-commit: + runs-on: ubuntu-24.04 + if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} + permissions: + contents: read + steps: + - name: Checkout PR head (no credentials) + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + persist-credentials: false + + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + cache: 'pip' + cache-dependency-path: | + requirements.txt + **/pyproject.toml + **/requirements*.txt + + - uses: actions/cache@v4 + with: + path: ~/.cache/pre-commit + key: pre-commit-${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }} + + - name: Install clang-format (Linux static binary) + run: | + sudo wget -qO /usr/local/bin/clang-format https://github.com/cpp-linter/clang-tools-static-binaries/releases/latest/download/clang-format-20_linux-amd64 + sudo chmod a+x /usr/local/bin/clang-format + clang-format --version + + - id: file_changes + uses: tj-actions/changed-files@v46 + + - name: Run pre-commit (changed files) + uses: pre-commit/action@v3.0.1 + with: + extra_args: --color always --files ${{ steps.file_changes.outputs.all_changed_files }} + + build-test: + name: Build & Test (forks, ${{ matrix.os }} / py${{ matrix.python-version }}) + runs-on: ${{ matrix.os }} + if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-24.04, macos-14] + python-version: ["3.9", "3.10", "3.11"] + permissions: + contents: read + packages: read + actions: read + security-events: write + steps: + - name: Checkout PR head (no credentials) + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + persist-credentials: false + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + cache-dependency-path: | + requirements.txt + **/pyproject.toml + **/requirements*.txt + + - name: Install system dependencies (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y \ + ninja-build build-essential \ + pkg-config autoconf automake libtool \ + zip unzip \ + bison swig \ + libdrm-dev \ + libx11-dev libxkbcommon-x11-dev libx11-xcb-dev \ + libxft-dev libxext-dev libgles2-mesa-dev \ + libxi-dev libxtst-dev libxrandr-dev libltdl-dev \ + libgtk2.0-dev \ + python3-setuptools python3-jinja2 python3-tk \ + mono-complete + + - name: Install system dependencies (macOS) + if: runner.os == 'macOS' + env: + HOMEBREW_NO_AUTO_UPDATE: 1 + HOMEBREW_NO_ANALYTICS: 1 + run: | + brew install ninja swig pkg-config mono || true + swig -version + mono --version || true + + - name: Setup CMake 3.28.3 + uses: jwlawson/actions-setup-cmake@v2 + with: + cmake-version: '3.28.3' + + - name: Install vcpkg + uses: lukka/run-vcpkg@v11 + with: + vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg' + vcpkgJsonGlob: "src/vcpkg.json" + vcpkgConfigurationJsonGlob: "src/vcpkg-configuration.json" + + - name: Add NuGet sources for vcpkg binary cache (read-only) + env: + VCPKG_EXE: ${{ runner.workspace }}/b/vcpkg/vcpkg + NUGET_USER: ${{ github.repository_owner }} + NUGET_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + NUGET="$(${VCPKG_EXE} fetch nuget | tail -n 1)" + + if [[ "$NUGET" == *.exe ]]; then + NUGET_CMD=(mono "$NUGET") + else + NUGET_CMD=("$NUGET") + fi + + echo "Using NuGet CLI: ${NUGET_CMD[*]}" + + "${NUGET_CMD[@]}" sources add \ + -Source "${FEED_URL}" \ + -Name GitHubPackages \ + -UserName "${NUGET_USER}" \ + -Password "${NUGET_TOKEN}" \ + -StorePasswordInClearText + + "${NUGET_CMD[@]}" setapikey "${NUGET_TOKEN}" \ + -Source "${FEED_URL}" + + - name: Create virtual environment + run: | + python -m venv .venv + source .venv/bin/activate + python -V + pip -V + + - name: Install required Python dependencies + run: | + source .venv/bin/activate + python -m pip install -r requirements.txt + + - name: Configure (CMake preset) + working-directory: src + run: cmake --preset fuzz-smoke-test + + - name: Build + working-directory: src + run: cmake --build ../build --parallel + + - name: Install Xmera (editable) + run: | + source .venv/bin/activate + cmake --install build --prefix $(pwd)/dist + python -m pip install -e . + + - name: Run Python tests + run: | + source .venv/bin/activate + cd src + pytest -n auto -m "not scenarioTest" + + - name: Run C/C++ unit tests (include fuzz-smoke) + working-directory: ./build + env: + CTEST_PARALLEL_LEVEL: 1 + run: ctest --output-on-failure -LE fuzz diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index c93c4a3f8..1d2971fd2 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -12,9 +12,8 @@ defaults: shell: bash --noprofile --norc -euo pipefail {0} env: - USERNAME: ${{ github.repository_owner }} FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json - VCPKG_BINARY_SOURCES: "clear;nuget,https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json,readwrite" + VCPKG_BINARY_SOURCES: "clear;nuget,https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json,read" VCPKG_FEATURE_FLAGS: "manifests,registries,binarycaching" CMAKE_BUILD_PARALLEL_LEVEL: 4 CTEST_PARALLEL_LEVEL: 4 @@ -25,6 +24,7 @@ jobs: runs-on: ubuntu-24.04 permissions: contents: read + if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} steps: - uses: actions/checkout@v4 @@ -59,7 +59,7 @@ jobs: build-test: name: Build & Test (${{ matrix.os }} / py${{ matrix.python-version }}) runs-on: ${{ matrix.os }} - if: ${{ github.event.pull_request.draft == false }} + if: ${{ github.event.pull_request.draft == false && github.event.pull_request.head.repo.full_name == github.repository }} strategy: fail-fast: false matrix: @@ -67,7 +67,7 @@ jobs: python-version: ["3.9", "3.10", "3.11"] permissions: contents: read - packages: write + packages: read actions: read security-events: write steps: @@ -132,18 +132,18 @@ jobs: ${{ runner.workspace }}/b/vcpkg/buildtrees key: vcpkg-${{ runner.os }}-${{ hashFiles('src/vcpkg.json', 'src/vcpkg-configuration.json') }} - - name: Add NuGet sources for vcpkg binary cache (portable) + - name: Add NuGet sources for vcpkg binary cache (read-only) env: VCPKG_EXE: ${{ runner.workspace }}/b/vcpkg/vcpkg + NUGET_USER: ${{ github.repository_owner }} + NUGET_TOKEN: ${{ github.token }} run: | set -euo pipefail NUGET="$(${VCPKG_EXE} fetch nuget | tail -n 1)" - # Build the command invocation safely (handles paths with spaces) if [[ "$NUGET" == *.exe ]]; then NUGET_CMD=(mono "$NUGET") else - # e.g., "nuget" shim from Mono on macOS, or a native path NUGET_CMD=("$NUGET") fi @@ -151,12 +151,12 @@ jobs: "${NUGET_CMD[@]}" sources add \ -Source "${FEED_URL}" \ - -StorePasswordInClearText \ -Name GitHubPackages \ - -UserName "${USERNAME}" \ - -Password "${{ secrets.GH_VCPKG_PACKAGES_TOKEN }}" + -UserName "${NUGET_USER}" \ + -Password "${NUGET_TOKEN}" \ + -StorePasswordInClearText - "${NUGET_CMD[@]}" setapikey "${{ secrets.GH_VCPKG_PACKAGES_TOKEN }}" \ + "${NUGET_CMD[@]}" setapikey "${NUGET_TOKEN}" \ -Source "${FEED_URL}" - name: Create virtual environment @@ -173,8 +173,6 @@ jobs: - name: Configure (CMake preset) working-directory: src - env: - VCPKG_BINARY_SOURCES: "clear;nuget,${{ env.FEED_URL }},readwrite" run: cmake --preset fuzz-smoke-test - name: Build