Skip to content

Keep a pinned feed on its tail while content resizes without a mutation #18

Keep a pinned feed on its tail while content resizes without a mutation

Keep a pinned feed on its tail while content resizes without a mutation #18

Workflow file for this run

name: CI
# Every push and pull request builds the solution and runs every test, the integration and slow
# ones included, on Windows, Linux and macOS at once. The process sandbox is enforced differently
# on each (AppContainer, Landlock, Seatbelt), so its tests only prove something on all three.
on:
push:
pull_request:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: Test (${{ matrix.os }})
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
timeout-minutes: 60
env:
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
# A runner that cannot enforce the sandbox fails the sandbox tests instead of skipping them.
AI_SANDBOX_REQUIRED: 1
steps:
- uses: actions/checkout@v7
- uses: actions/setup-dotnet@v6
with:
dotnet-version: 10.0.x
- name: Build
run: dotnet build AI.slnx --nologo
- name: Point TMPDIR at a real directory on macOS
if: runner.os == 'macOS'
shell: bash
# macOS's temporary directory lives behind the /var -> /private/var link. The application
# resolves links and reports the real path, while tests build expected paths from the
# temporary directory as spelled, so they would compare two names of one place.
run: echo "TMPDIR=${{ runner.temp }}/" >> "$GITHUB_ENV"
- name: Test
shell: bash
run: |
set -o pipefail
mkdir -p artifacts/test-results
dotnet test --solution AI.slnx --no-build --results-directory artifacts/test-results --no-ansi --no-progress 2>&1 | tee artifacts/test-results/test.log
# Each failed test becomes an annotation with its message, so a failure can be read from the
# run page and the checks API without downloading the logs.
- name: Report failed tests
if: failure()
shell: bash
run: |
# head ends the pipe early on purpose; that is not a failure of this step.
set +e +o pipefail
log=artifacts/test-results/test.log
# perl rather than sed: BSD sed on macOS does not understand \x1b.
plain() { perl -pe 's/\e\[[0-9;]*[A-Za-z]//g; s/\r$//' "$@"; }
failures=$(plain "$log" | awk '
/^[[:space:]]*failed / { if (block != "") print block; sub(/^[[:space:]]+/, ""); block = $0; lines = 0; next }
block != "" && lines < 14 { block = block "%0A" $0; lines++; next }
block != "" { print block; block = "" }
END { if (block != "") print block }
' | head -n 40)
if [ -z "$failures" ]; then
# Nothing looked like a failed test: the run broke some other way, so show how it ended.
echo "::error title=Test run tail::$(tail -n 40 "$log" | plain | perl -pe 's/%/%25/g' | awk '{ printf "%s%%0A", $0 }')"
fi
printf '%s\n' "$failures" | while IFS= read -r failure; do
[ -n "$failure" ] && echo "::error title=${failure%%\%0A*}::${failure}"
done
- name: Upload test results
if: failure()
uses: actions/upload-artifact@v7
with:
name: test-results-${{ matrix.os }}
path: artifacts/test-results
if-no-files-found: ignore