Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
*.sh text eol=lf

###############################################################################
# Set default behavior for command prompt diff.
Expand Down
142 changes: 64 additions & 78 deletions .github/workflows/buildtest.yml
Original file line number Diff line number Diff line change
@@ -1,93 +1,79 @@
---
name: Run Tests
name: Compare saved builds
on:
pull_request:
branches:
- dev
branches: [dev, tests-branch]
workflow_dispatch:
inputs:
base_ref:
description: Base commit or ref (empty uses this workflow's commit)
type: string
head_ref:
description: Candidate commit or ref (empty uses this workflow's commit)
type: string
strict:
description: Fail on stat differences as well as calculation errors
type: boolean
default: false
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
group: build-corpus-${{ github.ref }}
cancel-in-progress: true
jobs:
run_build_diff:
fixture_smoke:
name: Fixed fixture comparison
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout HEAD
uses: actions/checkout@v4
- name: Fetch Dev branch
id: get-dev-ref
run: |
git fetch --depth=1 origin dev
echo "devref=$(git rev-parse origin/dev)" >> $GITHUB_OUTPUT
- name: Download Dev branch cache
id: download-dev-ref-cache
uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da
with:
name: cache-devref-${{ steps.get-dev-ref.outputs.devref }}
path: /tmp/cache/
if_no_artifact_found: warn
search_artifacts: true
# Dev ref cache contains the build list and build xmls. Use that one to keep tests reproducible
- name: Update static builds list from cache
if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'true' }}
run: cat /tmp/cache/builds.txt > spec/builds.txt
- name: Download latest build list
if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' }}
id: download-build-list
uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
name: builds.txt
path: /tmp/latestbuildlist/
workflow: updatebuildlist.yml
if_no_artifact_found: warn
search_artifacts: true
- name: Update static builds list
if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' && steps.download-build-list.outputs.found_artifact == 'true' }}
run: cat /tmp/latestbuildlist/builds.txt > spec/builds.txt
- name: Download latest build xmls
if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' }}
uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
name: build-xmls
path: /tmp/cache/
if_no_artifact_found: warn
search_artifacts: true
- name: Calculate build xmls and differences between them
python-version: '3.12'
- name: Compare every fixed fixture on base and candidate
env:
BASE_REF: ${{ github.event.pull_request.base.sha || inputs.base_ref || github.sha }}
HEAD_REF: ${{ github.event.pull_request.head.sha || inputs.head_ref || github.sha }}
STRICT_DIFF: ${{ inputs.strict }}
run: |
mkdir /tmp/cache || true # Make sure /tmp/cache exists. Ignore exit code
chmod -R 777 /tmp/cache && docker compose run -v '/tmp/cache/:/cache' -e 'CACHEDIR=/cache' busted-diff | tee /tmp/dockerlog
- name: Generate artefact
args=()
if [ "$STRICT_DIFF" = true ]; then args+=(--strict); fi
python spec/RunBuildDiff.py --base "$BASE_REF" --head "$HEAD_REF" --fixtures-only --output "$RUNNER_TEMP/fixture-diff" "${args[@]}"
- name: Run importer and runner contract tests
run: |
sed -n '/Runtime comparison for/,/Savefile Diff for/{/Savefile Diff for/!p;}' /tmp/dockerlog > /tmp/artefact
sed -n '/Savefile Diff for/, $p' /tmp/dockerlog >> /tmp/artefact
[ -s /tmp/artefact ] || rm /tmp/artefact
- name: Upload artefact
uses: actions/upload-artifact@v4
with:
name: build-diff-output
path: /tmp/artefact
- name: Save used build list into cache
if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' }}
run: cp spec/builds.txt /tmp/cache/
- name: Move xmls found in builds.txt to a new directory
if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' && steps.download-build-list.outputs.found_artifact == 'true' }}
python -m unittest discover -s tests -p 'test_update_build_corpus.py' -v
python -m unittest discover -s tests -p 'test_build_diff_contract.py' -v
- name: Test output comparison semantics
run: |
mkdir new-build-xmls
while IFS= read -r line; do
FILENAME="/tmp/cache/${line//[^a-zA-Z0-9]/}.xml"
if [ -f "$FILENAME" ]; then
mv "$FILENAME" "./new-build-xmls/"
fi
done < "spec/builds.txt"
- name: Upload new build xmls
if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' && steps.download-build-list.outputs.found_artifact == 'true' }}
uses: actions/upload-artifact@v4
docker build -t pob-corpus-contracts -f Dockerfile.test-builds .
docker run --rm --network none --mount "type=bind,source=$PWD,target=/workdir,readonly" -w /workdir pob-corpus-contracts luajit tests/test_diff_output.lua
corpus_comparison:
name: Complete rotating corpus comparison
if: vars.TEST_BUILD_CORPUS_ENABLED == 'true' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
name: build-xmls
path: './new-build-xmls/*'
- name: Upload dev ref cache
if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' }}
uses: actions/upload-artifact@v4
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
name: cache-devref-${{ steps.get-dev-ref.outputs.devref }}
path: /tmp/cache/
python-version: '3.12'
- name: Pin saved corpus once
run: |
git fetch origin refs/heads/build-test-corpus
CORPUS_SHA=$(git rev-parse FETCH_HEAD)
echo "Pinned corpus commit: $CORPUS_SHA"
git worktree add --detach "$RUNNER_TEMP/corpus" "$CORPUS_SHA"
- name: Calculate all saved inputs without provider requests
env:
BASE_REF: ${{ github.event.pull_request.base.sha || inputs.base_ref || github.sha }}
HEAD_REF: ${{ github.event.pull_request.head.sha || inputs.head_ref || github.sha }}
STRICT_DIFF: ${{ inputs.strict }}
run: |
args=()
if [ "$STRICT_DIFF" = true ]; then args+=(--strict); fi
python spec/RunBuildDiff.py --base "$BASE_REF" --head "$HEAD_REF" --corpus "$RUNNER_TEMP/corpus" --output "$RUNNER_TEMP/corpus-diff" "${args[@]}"
6 changes: 6 additions & 0 deletions .github/workflows/unittest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@ on:
push:
branches:
- dev
- tests-branch
pull_request:
branches:
- dev
- tests-branch
permissions:
contents: read
jobs:
run_unit_tests:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Run busted tests
run: docker compose run --no-TTY busted-tests
70 changes: 40 additions & 30 deletions .github/workflows/updatebuildlist.yml
Original file line number Diff line number Diff line change
@@ -1,37 +1,47 @@
---
name: Update build list for tests
name: Refresh monthly build corpus
on:
schedule:
- cron: '20 4 * * *'
workflow_dispatch:
permissions:
contents: write
concurrency:
group: monthly-build-corpus-writer
cancel-in-progress: false
jobs:
update-builds-list:
runs-on: ubuntu-22.04
refresh:
if: github.event_name == 'workflow_dispatch' || (vars.TEST_BUILD_CORPUS_ENABLED == 'true' && github.ref_name == github.event.repository.default_branch)
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout HEAD
uses: actions/checkout@v4
- name: Install moreutils
run: sudo apt-get install -y moreutils
- name: Download latest build list
uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
name: builds.txt
if_no_artifact_found: warn
path: /tmp/latestbuildlist/
- name: Update list
run: >
cat spec/builds.txt /tmp/latestbuildlist/builds.txt
<({ curl "https://pobarchives.com/api/builds?q=latest" & curl "https://pobarchives.com/api/builds?q=trending"; }
| jq -r '.builds[].build_info.build_link')
| tail -n 500
| sort -u
| sponge builds.txt
- name: Print new builds list
run: cat builds.txt
- name: Save new build list
uses: actions/upload-artifact@v4
with:
name: builds.txt
path: builds.txt
overwrite: true
retention-days: 3
python-version: '3.12'
- name: Load saved corpus or bootstrap an empty branch
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
REMOTE_REF=$(git ls-remote origin refs/heads/build-test-corpus)
if [ -n "$REMOTE_REF" ]; then
git fetch origin refs/heads/build-test-corpus
git worktree add --detach "$RUNNER_TEMP/corpus" FETCH_HEAD
else
git worktree add --detach "$RUNNER_TEMP/corpus" HEAD
git -C "$RUNNER_TEMP/corpus" switch --orphan build-test-corpus
fi
- name: Validate and construct next corpus
run: python spec/UpdateBuildCorpus.py --url https://api.pob.codes/test-builds --prior "$RUNNER_TEMP/corpus" --output "$RUNNER_TEMP/next-corpus"
- name: Commit manifest and retained bytes together
run: |
git -C "$RUNNER_TEMP/corpus" rm -r --ignore-unmatch codes manifest.json
cp -a "$RUNNER_TEMP/next-corpus/." "$RUNNER_TEMP/corpus/"
git -C "$RUNNER_TEMP/corpus" add manifest.json codes
if git -C "$RUNNER_TEMP/corpus" diff --cached --quiet; then
echo "Monthly batch already applied; no corpus change."
exit 0
fi
git -C "$RUNNER_TEMP/corpus" commit -m "Refresh monthly test-build corpus"
# Plain fast-forward push rejects a competing writer. The next daily run
# refetches/reapplies; never force-push or publish a partial manifest.
git -C "$RUNNER_TEMP/corpus" push origin HEAD:refs/heads/build-test-corpus
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Builds/
Settings.xml

# Testing
__pycache__/
*.pyc
luajit/
spec/test_results.log
spec/test_generation.log
Expand All @@ -35,4 +37,4 @@ src/Export/ggpk/*.dll
src/Data/TimelessJewelData/*.bin

# Simplegraphic Debugging
runtime/imgui.ini
runtime/imgui.ini
3 changes: 3 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Contributing to Path of Building

For the monthly test-build feed, local calculation comparisons, and CI activation,
see [Build corpus CI](docs/build-corpus-ci.md).

# Table of contents
1. [Reporting bugs](#reporting-bugs)
2. [Requesting features](#requesting-features)
Expand Down
7 changes: 7 additions & 0 deletions Dockerfile.test-builds
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM ghcr.io/pathofbuildingcommunity/pathofbuilding-tests@sha256:171dc3da232b8c874882e4ae3b3aa4a6e130a6c9450a31904b312435a6bf5daf AS modern_luajit
FROM ghcr.io/paliak/busted-tests@sha256:0ce3f27d276dd6918d78ae11339e4135c445ea0e4fd31dbc88087ea25232ed90
RUN luarocks install luautf8 0.1.6-1
# Retain the existing test dependencies, but use upstream's GC64-capable LuaJIT.
COPY --from=modern_luajit /usr/local/bin/luajit-2.1.1784580905 /usr/local/bin/luajit-current
COPY --from=modern_luajit /usr/local/share/luajit-2.1 /usr/local/share/luajit-2.1
RUN ln -sf /usr/local/bin/luajit-current /usr/local/bin/luajit
2 changes: 2 additions & 0 deletions Dockerfile.test-builds.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
**
!Dockerfile.test-builds
Loading