name: CI on: push: branches: [master, develop] env: UV_VERSION: "0.8.0" PYTHON_VERSION: "3.13" NOX_DEFAULT_VENV_BACKEND: "uv" jobs: benchmark-regression: if: forgejo.event_name != 'pull_request' runs-on: docker-benchmark container: image: python:3.13-slim steps: - name: Install system dependencies (nodejs for checkout, git for merge tests) run: | apt-get update && apt-get install -y -qq nodejs git && rm -rf /var/lib/apt/lists/* - name: Checkout full history uses: actions/checkout@v4 with: fetch-depth: 0 - name: Compute base commit id: hash run: | git fetch origin "${{ forgejo.base_ref }}" --depth=200 BASE_SHA=$(git merge-base HEAD "origin/${{ forgejo.base_ref }}") echo "ASV_BASE_SHA=${BASE_SHA}" >> $FORGEJO_OUTPUT - name: Install dependencies run: | python -m pip install -U pip python -m pip install asv virtualenv uv==${{ env.UV_VERSION }} nox - name: Restore prior ASV benchmarks env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} ASV_S3_BUCKET: ${{ secrets.ASV_S3_BUCKET }} run: | python -m pip install awscli mkdir -p build/asv/results aws s3 sync "s3://${ASV_S3_BUCKET}/asv/results" build/asv/results --delete || true - name: Run asv continuous via nox env: ASV_BASE_SHA: ${{ steps.hash.outputs.ASV_BASE_SHA }} run: | nox -s benchmark_regression - name: Archive the results run: | tar cf /tmp/asv-results.tar build/asv/results build/asv/html - name: Upload benchmark artifacts if: always() uses: actions/upload-artifact@v3 with: name: asv-results-pr path: /tmp/asv-results.tar retention-days: 30 benchmark-publish: if: forgejo.event_name == 'push' runs-on: docker-benchmark container: python:3.13-slim steps: - name: Install system dependencies (nodejs for checkout, git for merge tests) run: | apt-get update && apt-get install -y -qq nodejs git && rm -rf /var/lib/apt/lists/* - name: Checkout full history uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install dependencies run: | python -m pip install -U pip python -m pip install asv virtualenv uv==${{ env.UV_VERSION }} nox - name: Restore prior ASV benchmarks env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} ASV_S3_BUCKET: ${{ secrets.ASV_S3_BUCKET }} run: | python -m pip install awscli mkdir -p build/asv/results aws s3 sync "s3://${ASV_S3_BUCKET}/asv/results" build/asv/results --delete || true - name: Run asv via nox run: | nox -s benchmark - name: Upload updated benchmarks and website to S3 env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} ASV_S3_BUCKET: ${{ secrets.ASV_S3_BUCKET }} run: | python -m pip install awscli aws s3 sync build/asv/results "s3://${ASV_S3_BUCKET}/asv/results" --delete aws s3 sync build/asv/html "s3://${ASV_S3_BUCKET}/asv/html" --delete - name: Archive the results run: | tar cf /tmp/asv-results.tar build/asv/results build/asv/html - name: Upload benchmark artifacts if: always() uses: actions/upload-artifact@v3 with: name: asv-results-pr path: /tmp/asv-results.tar retention-days: 30 e2e_tests: if: forgejo.event_name == 'push' runs-on: docker timeout-minutes: 45 container: image: python:3.13-slim steps: - name: Install system dependencies (nodejs for checkout, git for E2E tests) run: | apt-get update && apt-get install -y -qq nodejs git && rm -rf /var/lib/apt/lists/* - uses: actions/checkout@v4 - name: Install uv and nox run: | pip install -q uv==${{ env.UV_VERSION }} nox - name: Cache uv packages uses: actions/cache@v3 with: path: ~/.cache/uv key: uv-${{ hashFiles('pyproject.toml') }} restore-keys: | uv- - name: Install dependencies run: | python -m pip install -U pip python -m pip install asv virtualenv uv==${{ env.UV_VERSION }} nox - name: Sync prior benchmark results from S3 id: s3-sync env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} ASV_S3_BUCKET: ${{ secrets.ASV_S3_BUCKET }} run: | BASICSYNC_EXIT=0 if [ -n "${AWS_ACCESS_KEY_ID}" ] && [ -n "${ASV_S3_BUCKET}" ]; then python -m pip install awscli mkdir -p build/asv/results aws s3 sync "s3://${ASV_S3_BUCKET}/asv/results/" build/asv/results/ || true if ls build/asv/results/*/hash_to_id.json 1>/dev/null 2>&1; then echo "# has_baseline=true" > build/.benchmark-baseline else echo "# has_baseline=false" > build/.benchmark-baseline fi else echo "Skipping S3 sync - AWS credentials not configured" echo "# has_baseline=false" > build/.benchmark-baseline fi - name: Run benchmark regression via nox id: asv-run env: NOX_DEFAULT_VENV_BACKEND: uv ASV_BASE_SHA: master run: | mkdir -p build/asv/results build/asv/html # Check whether baseline data exists before running benchmarks if [[ ! -f build/.benchmark-baseline ]] || grep -q "has_baseline=false" build/.benchmark-baseline; then echo "Benchmark regression skipped: no S3 baseline results available to compare against." echo "This is expected when ASV results have not been published from the scheduled benchmark workflow." echo "SKIPPED: no baseline data available for regression comparison" > build/nox-benchmark-regression-output.log else echo "Running benchmark regression with S3 baseline..." nox -s benchmark_regression 2>&1 | tee build/nox-benchmark-regression-output.log || true fi - name: Upload E2E tests log artifact if: failure() uses: actions/upload-artifact@v3 with: name: ci-logs-e2e-tests path: | build/nox-e2e-tests-output.log build/reports/robot-e2e/ retention-days: 30