Skip to content
Merged
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
35 changes: 31 additions & 4 deletions .github/scripts/test_release_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
MATRIX113 = MATRIX112 + [origin + ' / ' + stamps for origin in
['released-112', 'recovery-112', 'via112-110', 'via112-111']
for stamps in ['normal', 'stamps']]
MATRIX114 = MATRIX113 + [origin + ' / ' + stamps for origin in
['released-113', 'recovery-113', 'via113-110', 'via113-111', 'via113-112']
for stamps in ['normal', 'stamps']]
MATRIX = [origin + ' / ' + stamps for origin in
['original-110', 'released-110', 'original-111', 'recovery-110']
for stamps in ['normal', 'stamps']]
Expand Down Expand Up @@ -53,7 +56,8 @@ def validate(self, minecraft, names=None, mutation=None, release_exists=False, w
'1.10.2': ('110021', '1.10.2', '12.18.3.2511'),
'1.11.2': ('111021', '1.11.2-dev', '13.20.1.2588'),
'1.12.2': ('112021', 'master-1.12', '14.23.5.2859'),
'1.13.2': ('113021', 'master-1.13.2', '25.0.223')}[minecraft]
'1.13.2': ('113021', 'master-1.13.2', '25.0.223'),
'1.14.4': ('114041', 'master-1.14.4', '28.2.26')}[minecraft]
version = '2.4.2.' + suffix
values = dict(minecraft_version=minecraft, forge_version=forge, loader_name='forge', loader_code='1',
java_version='8', java_toolchain_version='8.0.502+7', gradle_java_version='17', mod_id='lootablebodies',
Expand All @@ -62,7 +66,8 @@ def validate(self, minecraft, names=None, mutation=None, release_exists=False, w
if mutation:
values.update(mutation)
checks = CORE + {'1.11.2': MATRIX, '1.12.2': MATRIX112,
'1.13.2': MATRIX113 + ['Validate release workflow']}.get(minecraft, []) if names is None else names
'1.13.2': MATRIX113 + ['Validate release workflow'],
'1.14.4': MATRIX114 + ['Validate release workflow']}.get(minecraft, []) if names is None else names
def command(args, **options):
if args[0] == 'git':
return SHA + '\n'
Expand All @@ -85,16 +90,21 @@ def existing(args, **options):
patch('subprocess.check_output', side_effect=command), patch('subprocess.run', side_effect=existing):
exec(compile(code, 'release-preflight', 'exec'), {})

def test_future_115_candidate_cannot_dispatch_publication(self):
code, values = self.select('2.4.6.115021')
self.assertNotEqual(0, code)
self.assertEqual({}, values)

def test_routes_all_supported_versions(self):
for suffix, minecraft, branch in [('110021', '1.10.2', '1.10.2'), ('111021', '1.11.2', '1.11.2-dev'), ('112021', '1.12.2', 'master-1.12'), ('113021', '1.13.2', 'master-1.13.2')]:
for suffix, minecraft, branch in [('110021', '1.10.2', '1.10.2'), ('111021', '1.11.2', '1.11.2-dev'), ('112021', '1.12.2', 'master-1.12'), ('113021', '1.13.2', 'master-1.13.2'), ('114041', '1.14.4', 'master-1.14.4')]:
with self.subTest(minecraft=minecraft):
status, values = self.select('2.4.2.' + suffix)
self.assertEqual(0, status)
self.assertEqual(minecraft, values['minecraft_version'])
self.assertEqual(branch, values['source_branch'])

def test_invalid_versions_are_rejected(self):
for version in ['2.4.2', '2.4.2.114041', '02.4.2.111021', '2.4.2.111021;exit 0']:
for version in ['2.4.2', '2.4.2.114021', '02.4.2.111021', '2.4.2.111021;exit 0']:
with self.subTest(version=version):
self.assertNotEqual(0, self.select(version)[0])

Expand Down Expand Up @@ -143,6 +153,23 @@ def test_113_audit_receives_the_registered_shared_ci_completion(self):
event_names = audit.split('workflows: [', 1)[1].split(']', 1)[0].split(',')
self.assertIn('LootableBodies 1.12 CI', [name.strip() for name in event_names])

def test_114_requires_every_upgrade_case_and_workflow_validation(self):
self.validate('1.14.4')
required = MATRIX114 + ['Validate release workflow']
self.assertEqual(34, len(MATRIX114))
for missing in required:
with self.subTest(missing=missing), self.assertRaises(SystemExit):
self.validate('1.14.4', names=CORE + [name for name in required if name != missing])

def test_114_requires_an_independent_audit_of_its_exact_artifact(self):
with self.assertRaises(SystemExit):
self.validate('1.14.4', audit_success=False)

def test_114_audit_receives_the_registered_shared_ci_completion(self):
audit = WORKFLOW.with_name('artifact-audit-1.14.yml').read_text(encoding='utf-8')
event_names = audit.split('workflows: [', 1)[1].split(']', 1)[0].split(',')
self.assertIn('LootableBodies 1.12 CI', [name.strip() for name in event_names])

def test_identity_changes_are_rejected(self):
for mutation in [{'mod_id': 'other'}, {'minecraft_version': '1.10.2'}, {'mod_license': 'CC0-1.0'}]:
with self.subTest(mutation=mutation), self.assertRaises(SystemExit):
Expand Down
64 changes: 64 additions & 0 deletions .github/workflows/artifact-audit-1.14.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Audit LootableBodies 1.14 artifacts
run-name: Audit 1.14.4 artifacts from ${{ github.event.workflow_run.head_sha }}

on:
workflow_run:
workflows: [LootableBodies 1.12 CI, LootableBodies 1.14 CI]
types: [completed]

permissions:
contents: read
actions: read

jobs:
audit:
# Pull-request merge trees are audited inside CI. Push artifacts use the
# workflow run's exact head SHA, which is also their declared artifact name.
if: >-
github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' &&
(github.event.workflow_run.head_branch == 'master-1.14.4')
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ github.event.workflow_run.head_sha }}
- uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
with:
distribution: temurin
java-version: '25.0.3+9.0.LTS'
- uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
with:
distribution: temurin
java-version: '8.0.502+7'
- uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
with:
distribution: temurin
java-version: '17.0.1+12'
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: LootableBodies-1.14.4-${{ github.event.workflow_run.head_sha }}
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
path: downloaded
- name: Require exact inputs and assemble an immutable audit bundle
run: |
set -euo pipefail
mkdir audited
for name in LootableBodies-2.4.5.114041.jar LootableBodies-2.4.5.114041-sources.jar LootableBodies-2.4.5.114041-javadoc.jar; do
test -s "downloaded/build/libs/$name"
cp "downloaded/build/libs/$name" audited/
done
test -s downloaded/build/release/SHA256SUMS
test -s downloaded/build/publications/mavenJava/pom-default.xml
test -s downloaded/CHANGELOG.txt
cp downloaded/build/release/SHA256SUMS audited/
cp downloaded/build/publications/mavenJava/pom-default.xml audited/LootableBodies-2.4.5.114041.pom
cp downloaded/CHANGELOG.txt audited/
- name: Audit original bytes without recompiling the jars
env:
LOOTABLEBODIES_JAVA8_HOME: ${{ env.JAVA_HOME_8_X64 }}
LOOTABLEBODIES_MAVENIZER_JAVA_HOME: ${{ env.JAVA_HOME_25_X64 }}
run: |
chmod +x ./gradlew
./gradlew verifyPreparedReleaseArtifacts -PpreparedReleaseDir=audited --no-daemon
64 changes: 51 additions & 13 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
name: LootableBodies 1.13 CI
name: LootableBodies 1.14 CI

on:
push:
branches:
- master-1.13.2
- master-1.14.4
- 'feature/**'
pull_request:
branches:
- master-1.13.2
- master-1.14.4

permissions:
contents: read

concurrency:
group: lootablebodies-1.13-${{ github.workflow }}-${{ github.ref }}
group: lootablebodies-1.14-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
Expand Down Expand Up @@ -141,6 +141,9 @@ jobs:
python3 tools/native_runtime.py --java "$JAVA_HOME_8_X64/bin/java" --output build/native-server-distribution
python3 tools/native_runtime.py --java "$JAVA_HOME_8_X64/bin/java" --output build/native-client-distribution --client

- name: Verify the independent native respawn control
run: xvfb-run -a -s '-screen 0 1280x720x24 +extension GLX +render -noreset' python3 tools/verify_native_respawn_control.py --java "$JAVA_HOME_8_X64/bin/java" --forge-home build/native-server-distribution --forge-client-home build/native-client-distribution --output build/native-respawn-control

- name: Verify packaged servers and malformed inventory recovery
run: |
python3 tools/verify_packaged.py --java "$JAVA_HOME_8_X64/bin/java" --forge-home build/native-server-distribution --output build/packaged-runtime
Expand All @@ -157,7 +160,23 @@ jobs:
xvfb-run -a -s '-screen 0 1280x720x24 +extension GLX +render -noreset' python3 tools/verify_packaged_client.py --java "$JAVA_HOME_8_X64/bin/java" --forge-client-home build/native-client-distribution --output "build/packaged-client-$mode" --mode "$mode"
done

- name: Verify recovery after a rejected first interaction
env:
JAVA_TOOL_OPTIONS: -Dlootablebodies.rejectFirstCorpseOpen=true -Dlootablebodies.issueClient.offsetViewer=true
run: |
xvfb-run -a -s '-screen 0 1280x720x24 +extension GLX +render -noreset' python3 tools/verify_packaged_client.py --java "$JAVA_HOME_8_X64/bin/java" --forge-client-home build/native-client-distribution --output build/packaged-client-rejected-interaction --mode issues
python3 - <<'PY'
from pathlib import Path
log = Path('build/packaged-client-rejected-interaction/client.log').read_text()
assert log.count('CORPSE_GUI_FIRST_INTERACTION_REJECTED_CONTROL') == 1
assert 'ISSUE5_VIEWER_APPROACH corpse=' in log
assert 'ISSUE5_DISTANT_VIEWER_CONFIRMED corpse=' in log
assert 'LOOTABLE_BODIES_ISSUE5_CLIENT_PASS' in log
PY

- name: Verify two-player inventory, death and visibility
env:
JAVA_TOOL_OPTIONS: -Dlootablebodies.visibility.offsetFirstDeath=true
run: |
xvfb-run -a -s '-screen 0 1280x720x24 +extension GLX +render -noreset' python3 tools/verify_multiplayer.py --java "$JAVA_HOME_8_X64/bin/java" --forge-home build/native-server-distribution --forge-client-home build/native-client-distribution --output build/packaged-multiplayer
xvfb-run -a -s '-screen 0 1280x720x24 +extension GLX +render -noreset' python3 tools/verify_visibility.py --java "$JAVA_HOME_8_X64/bin/java" --forge-home build/native-server-distribution --forge-client-home build/native-client-distribution --output build/packaged-visibility --mode visibility
Expand All @@ -173,41 +192,53 @@ jobs:
xvfb-run -a -s '-screen 0 1280x720x24 +extension GLX +render -noreset' python3 tools/verify_visibility.py --java "$JAVA_HOME_8_X64/bin/java" --forge-home build/native-server-distribution --forge-client-home build/native-client-distribution --output build/packaged-respawn-restart --mode respawn --cases 16 --source-server build/packaged-respawn-ordinary/server --simultaneous --counter-collision

- name: Audit complete runtime logs
run: python3 tools/audit_runtime_logs.py --native --recursive build/integration-run build/upgrade-contract-run build/client-integration-run build/packaged-runtime build/packaged-nbt build/ordinary-development build/ordinary-packaged build/packaged-client-default build/packaged-client-config build/packaged-client-skin build/packaged-client-issues build/packaged-client-names build/packaged-multiplayer build/packaged-visibility build/packaged-visibility-restart build/packaged-respawn-ordinary build/packaged-respawn-simultaneous build/packaged-respawn-restart build/packaged-respawn-counter-collision
run: python3 tools/audit_runtime_logs.py --native --recursive build/native-respawn-control build/integration-run build/upgrade-contract-run build/client-integration-run build/packaged-runtime build/packaged-nbt build/ordinary-development build/ordinary-packaged build/packaged-client-default build/packaged-client-config build/packaged-client-skin build/packaged-client-issues build/packaged-client-names build/packaged-multiplayer build/packaged-visibility build/packaged-visibility-restart build/packaged-respawn-ordinary build/packaged-respawn-simultaneous build/packaged-respawn-restart build/packaged-respawn-counter-collision

- name: Compare a second complete build
run: |
mkdir -p .gradle/repro-first
for name in LootableBodies-2.4.4.113021.jar LootableBodies-2.4.4.113021-sources.jar LootableBodies-2.4.4.113021-javadoc.jar; do
for name in LootableBodies-2.4.5.114041.jar LootableBodies-2.4.5.114041-sources.jar LootableBodies-2.4.5.114041-javadoc.jar; do
cp "build/libs/$name" .gradle/repro-first/
done
cp build/release/SHA256SUMS .gradle/repro-first/
./gradlew build javadoc prepareReleaseBundle --rerun-tasks --no-build-cache --no-daemon
for name in LootableBodies-2.4.4.113021.jar LootableBodies-2.4.4.113021-sources.jar LootableBodies-2.4.4.113021-javadoc.jar; do
for name in LootableBodies-2.4.5.114041.jar LootableBodies-2.4.5.114041-sources.jar LootableBodies-2.4.5.114041-javadoc.jar; do
cmp ".gradle/repro-first/$name" "build/libs/$name"
done
cmp .gradle/repro-first/SHA256SUMS build/release/SHA256SUMS
python3 tools/verify_release_setup.py --output build/release-contracts

- name: Require all declared reports and artifacts
run: |
for path in build/libs/LootableBodies-2.4.4.113021.jar build/libs/LootableBodies-2.4.4.113021-sources.jar build/libs/LootableBodies-2.4.4.113021-javadoc.jar build/release/SHA256SUMS build/publications/mavenJava/pom-default.xml CHANGELOG.txt build/packaged-runtime/result.json build/packaged-nbt/result.json build/ordinary-development/result.json build/ordinary-packaged/result.json build/packaged-client-default/result.json build/packaged-client-config/result.json build/packaged-client-skin/result.json build/packaged-client-issues/result.json build/packaged-client-names/result.json build/packaged-multiplayer/result.json build/packaged-visibility/result.json build/packaged-visibility-restart/result.json build/packaged-respawn-ordinary/result.json build/packaged-respawn-simultaneous/result.json build/packaged-respawn-restart/result.json build/packaged-respawn-counter-collision/result.json build/release-contracts/result.json; do
for path in build/native-respawn-control/result.json build/libs/LootableBodies-2.4.5.114041.jar build/libs/LootableBodies-2.4.5.114041-sources.jar build/libs/LootableBodies-2.4.5.114041-javadoc.jar build/release/SHA256SUMS build/publications/mavenJava/pom-default.xml CHANGELOG.txt build/packaged-runtime/result.json build/packaged-nbt/result.json build/ordinary-development/result.json build/ordinary-packaged/result.json build/packaged-client-default/result.json build/packaged-client-config/result.json build/packaged-client-skin/result.json build/packaged-client-issues/result.json build/packaged-client-names/result.json build/packaged-multiplayer/result.json build/packaged-visibility/result.json build/packaged-visibility-restart/result.json build/packaged-respawn-ordinary/result.json build/packaged-respawn-simultaneous/result.json build/packaged-respawn-restart/result.json build/packaged-respawn-counter-collision/result.json build/release-contracts/result.json; do
test -s "$path"
done
test -s build/test-results/test/TEST-cyano.lootable.contracts.NativeUpgradeBoundaryTest.xml
test -s build/test-results/test/TEST-cyano.lootable.network.LoginReadGuardTest.xml
test -s build/upgrade-contract-run/world/upgrade-contracts.pass

- name: Keep native control evidence
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: Native-Forge-28-control-${{ github.sha }}
if-no-files-found: error
retention-days: 30
path: |
build/native-respawn-control/result.json
build/native-respawn-control/*.log
build/native-respawn-control/server/logs/*.log
build/native-respawn-control/client/logs/*.log

- name: Upload audited local candidate
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: LootableBodies-1.13.2-${{ github.sha }}
name: LootableBodies-1.14.4-${{ github.sha }}
if-no-files-found: error
retention-days: 30
path: |
build/libs/LootableBodies-2.4.4.113021.jar
build/libs/LootableBodies-2.4.4.113021-sources.jar
build/libs/LootableBodies-2.4.4.113021-javadoc.jar
build/libs/LootableBodies-2.4.5.114041.jar
build/libs/LootableBodies-2.4.5.114041-sources.jar
build/libs/LootableBodies-2.4.5.114041-javadoc.jar
build/release/SHA256SUMS
build/publications/mavenJava/pom-default.xml
CHANGELOG.txt
Expand All @@ -216,7 +247,8 @@ jobs:
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: LootableBodies-1.13.2-diagnostics-${{ github.sha }}
name: LootableBodies-1.14.4-diagnostics-${{ github.sha }}
include-hidden-files: true
if-no-files-found: error
retention-days: 14
path: |
Expand All @@ -227,3 +259,9 @@ jobs:
build/**/screenshots/*.png
build/**/result.json
build/**/*checks.txt
.gradle/legacy-tools/released-112/build.log
.gradle/legacy-tools/released-113/build.log
build/packaged-client-issues/config/*.toml
build/packaged-client-issues/saves/issue-fixture/level.dat
build/packaged-client-issues/saves/issue-fixture/region/*.mca
build/packaged-client-issues/saves/issue-fixture/playerdata/*.dat
4 changes: 2 additions & 2 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ name: CodeQL
on:
push:
branches:
- master-1.13.2
- master-1.14.4
- 'feature/**'
pull_request:
branches:
- master-1.13.2
- master-1.14.4
schedule:
- cron: '43 7 * * 4'

Expand Down
Loading
Loading