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
33 changes: 26 additions & 7 deletions .github/scripts/test_release_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,14 @@ def validate(self, minecraft, names=None, mutation=None, release_exists=False, w
'1.16.5': ('116051', 'master-1.16.5', '36.2.42'),
'1.17.1': ('117011', 'master-1.17.1', '37.1.1'),
'1.18.2': ('118021', 'master-1.18.2', '40.3.12'),
'1.19.4': ('119041', 'master-1.19.4', '45.4.5')}[minecraft]
'1.19.4': ('119041', 'master-1.19.4', '45.4.5'),
'1.20.1': ('120011', 'master-1.20.1', '47.4.28')}[minecraft]
version = '2.4.2.' + suffix
files={name:'C'*64 for name in ['main.jar','sources.jar','javadoc.jar','release.pom','CHANGELOG.txt','SHA256SUMS']}
receipt={'schema':1,'source':SHA,'version':version,'files':files,'evidence_sha256':'F'*64,'qualified_locally':True,'manual_accepted':True}
if local_receipt is not None:receipt=local_receipt
values = dict(minecraft_version=minecraft, forge_version=forge, loader_name='forge', loader_code='1',
java_version='17' if minecraft in ('1.18.2','1.19.4') else '16' if minecraft=='1.17.1' else '8', java_toolchain_version='17.0.20.1+1' if minecraft in ('1.18.2','1.19.4') else '16.0.2+7' if minecraft=='1.17.1' else '8.0.502+7', gradle_java_version='17', mod_id='lootablebodies',
java_version='17' if minecraft in ('1.18.2','1.19.4','1.20.1') else '16' if minecraft=='1.17.1' else '8', java_toolchain_version='17.0.20.1+1' if minecraft in ('1.18.2','1.19.4','1.20.1') else '16.0.2+7' if minecraft=='1.17.1' else '8.0.502+7', gradle_java_version='17', mod_id='lootablebodies',
mod_artifact='LootableBodies', mod_group='zone.moddev.mc.lootablebodies', mod_license='LGPL-2.1-only',
curseforge_project_id='240968', mod_version=version)
if mutation:
Expand All @@ -86,13 +87,13 @@ def validate(self, minecraft, names=None, mutation=None, release_exists=False, w
'1.14.4': MATRIX114 + ['Validate release workflow'],
'1.15.2': MATRIX115, '1.16.5': MATRIX116}.get(minecraft, []) if names is None else names
if minecraft=='1.17.1' and names is None:checks=CORE117+MATRIX117
if minecraft in ('1.18.2','1.19.4') and names is None:checks=CORE118
if minecraft in ('1.18.2','1.19.4','1.20.1') and names is None:checks=CORE118

def command(args, **options):
if args[0] == 'git':
return SHA + '\n'
if any('/actions/workflows/native'+code+'.yml/' in args[-1] for code in ['117','118','119']):
code={'1.17.1':'117','1.18.2':'118','1.19.4':'119'}[minecraft]
if any('/actions/workflows/native'+code+'.yml/' in args[-1] for code in ['117','118','119','120']):
code={'1.17.1':'117','1.18.2':'118','1.19.4':'119','1.20.1':'120'}[minecraft]
row=dict(id=int(code),head_sha=SHA,head_branch=branch,event='push',path='.github/workflows/native'+code+'.yml',conclusion='success')
if qualification:row.update(qualification)
return json.dumps({'workflow_runs':[row]})
Expand All @@ -116,8 +117,8 @@ 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_120_candidate_cannot_dispatch_publication(self):
code, values = self.select('2.4.11.120011')
def test_future_1206_candidate_cannot_dispatch_publication(self):
code, values = self.select('2.4.12.120061')
self.assertNotEqual(0, code)
self.assertEqual({}, values)

Expand Down Expand Up @@ -336,6 +337,24 @@ def test_119_requires_manual_acceptance_and_exact_artifacts(self):
self.assertNotIn('gradlew', step)
self.assertIn("minecraft_version == '1.19.4' && 'Java 17'", WORKFLOW.read_text())

def test_120_requires_manual_acceptance_and_exact_artifacts(self):
code, values = self.select('2.4.11.120011')
self.assertEqual(0, code)
self.assertEqual('master-1.20.1', values['source_branch'])
self.validate('1.20.1')
for missing in CORE118:
with self.subTest(missing=missing), self.assertRaises(SystemExit):
self.validate('1.20.1', names=[name for name in CORE118 if name != missing])
for kwargs in [{'audit_success':False}, {'local_receipt':{}},
{'qualification':{'path':'.github/workflows/native118.yml'}},
{'mutation':{'java_version':'8'}}]:
with self.subTest(kwargs=kwargs), self.assertRaises(SystemExit):
self.validate('1.20.1', **kwargs)
step = WORKFLOW.read_text().split('- name: Verify all six native120 bytes before publication', 1)[1].split(' - name:', 1)[0]
self.assertIn('python3 -B tools/native120_build.py --bundle build/release/bundle', step)
self.assertNotIn('gradlew', step)
self.assertIn("minecraft_version == '1.20.1' && 'Java 17'", WORKFLOW.read_text())

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
48 changes: 48 additions & 0 deletions .github/workflows/artifact-audit-1.20.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Audit LootableBodies 1.20 artifacts
run-name: Audit 1.20.1 artifacts from ${{ github.event.workflow_run.head_sha }}
on:
workflow_run:
workflows: [LootableBodies 1.20 CI]
types: [completed]
permissions:
contents: read
actions: read
jobs:
audit:
if: >-
github.repository == 'MinecraftModDevelopmentMods/LootableBodies' &&
github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' &&
github.event.workflow_run.head_branch == 'master-1.20.1'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ github.event.workflow_run.head_sha }}
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: LootableBodies-1.20.1-${{ github.event.workflow_run.head_sha }}
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
path: audited
- name: Independently verify every locally qualified byte
env:
SOURCE_SHA: ${{ github.event.workflow_run.head_sha }}
run: |
python3 -B tools/native120_build.py --bundle audited
python3 - <<'PY'
import json,os
from pathlib import Path
accepted=json.loads(Path('.github/release120.json').read_text())
Path('independent-audit.json').write_text(json.dumps({'source':os.environ['SOURCE_SHA'],'files':accepted['files'],'all_six_exact':True,'identical_to_locally_audited_bundle':True},indent=2)+'\n')
PY
# Exact hashes reuse the local class61/licence/identity/mapping audit.
# This independent receipt is a byte match, not a fresh gameplay run or
# another Gradle/Forge preparation. The build job audits new archives.
- name: Retain independent audit evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: native120-independent-audit-${{ github.event.workflow_run.head_sha }}
if-no-files-found: error
path: independent-audit.json
Loading
Loading