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
17 changes: 17 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
* text=auto
*.java text eol=lf
*.gradle text eol=lf
*.properties text eol=lf
*.json text eol=lf
*.lang text eol=lf
*.mcmeta text eol=lf
*.info text eol=lf
*.md text eol=lf
*.txt text eol=lf
LICENSE* text eol=lf
*.yml text eol=lf
*.py text eol=lf
gradlew text eol=lf
*.bat text eol=crlf
*.jar binary
*.png binary
29 changes: 23 additions & 6 deletions .github/scripts/test_release_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
REPOSITORY = 'MinecraftModDevelopmentMods/LootableBodies'
SHA = 'a' * 40
CORE = ['Cold Forge bootstrap', 'Build, test, and audit', 'Analyze Java', 'Validation']
MATRIX112 = [origin + ' / ' + stamps for origin in
['original-110', 'released-110', 'original-111', 'recovery-110',
'released-111', 'original-112', 'recovery-111', 'via111-110']
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 @@ -42,20 +46,23 @@ def select(self, version, repository=REPOSITORY, ref='refs/heads/master-1.12'):
return result.returncode, values

def validate(self, minecraft, names=None, mutation=None, release_exists=False, wrong_tag=False, audit_success=True):
suffix, branch, forge = ('110021', '1.10.2', '12.18.3.2511') if minecraft == '1.10.2' else ('111021', '1.11.2-dev', '13.20.1.2588')
suffix, branch, forge = {
'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')}[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',
mod_artifact='LootableBodies', mod_group='zone.moddev.mc.lootablebodies', mod_license='LGPL-2.1-only',
curseforge_project_id='240968', mod_version=version)
if mutation:
values.update(mutation)
checks = CORE + (MATRIX if minecraft == '1.11.2' else []) if names is None else names
checks = CORE + {'1.11.2': MATRIX, '1.12.2': MATRIX112}.get(minecraft, []) if names is None else names
def command(args, **options):
if args[0] == 'git':
return SHA + '\n'
if '/actions/workflows/' in args[-1]:
return json.dumps({'workflow_runs': [{'id': 1, 'display_title': 'Audit 1.11.2 artifacts from ' + SHA,
return json.dumps({'workflow_runs': [{'id': 1, 'display_title': 'Audit ' + minecraft + ' artifacts from ' + SHA,
'conclusion': 'success' if audit_success else 'failure'}]})
return json.dumps({'check_runs': [dict(name=name, id=i, conclusion='success') for i, name in enumerate(checks)]})
def existing(args, **options):
Expand All @@ -73,16 +80,16 @@ 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_routes_both_supported_versions(self):
for suffix, minecraft, branch in [('110021', '1.10.2', '1.10.2'), ('111021', '1.11.2', '1.11.2-dev')]:
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')]:
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.112021', '02.4.2.111021', '2.4.2.111021;exit 0']:
for version in ['2.4.2', '2.4.2.113021', '02.4.2.111021', '2.4.2.111021;exit 0']:
with self.subTest(version=version):
self.assertNotEqual(0, self.select(version)[0])

Expand All @@ -103,6 +110,16 @@ def test_111_requires_an_independent_audit_of_its_exact_artifact(self):
with self.assertRaises(SystemExit):
self.validate('1.11.2', audit_success=False)

def test_112_requires_every_upgrade_case(self):
self.validate('1.12.2')
for missing in MATRIX112:
with self.subTest(missing=missing), self.assertRaises(SystemExit):
self.validate('1.12.2', names=CORE + [name for name in MATRIX112 if name != missing])

def test_112_requires_an_independent_audit_of_its_exact_artifact(self):
with self.assertRaises(SystemExit):
self.validate('1.12.2', audit_success=False)

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
2 changes: 1 addition & 1 deletion .github/workflows/artifact-audit-1.11.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ run-name: Audit 1.11.2 artifacts from ${{ github.event.workflow_run.head_sha }}

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

permissions:
Expand Down
64 changes: 64 additions & 0 deletions .github/workflows/artifact-audit-1.12.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Audit LootableBodies 1.12 artifacts
run-name: Audit 1.12.2 artifacts from ${{ github.event.workflow_run.head_sha }}

on:
workflow_run:
workflows: [LootableBodies 1.10 CI, LootableBodies 1.11 CI, LootableBodies 1.12 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.12.2' || github.event.workflow_run.head_branch == 'master-1.12')
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.12.2-${{ 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.3.112021.jar LootableBodies-2.4.3.112021-sources.jar LootableBodies-2.4.3.112021-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.3.112021.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
Loading
Loading