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
64 changes: 64 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: CI

# Do not use event-level path filters: GitHub truncates their changed-file list.
on:
pull_request:
push:
branches: [main]

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: true

jobs:
changes:
runs-on: ubuntu-24.04
timeout-minutes: 3
outputs:
lua: ${{ steps.paths.outputs.lua }}
python: ${{ steps.paths.outputs.python }}
package: ${{ steps.paths.outputs.package }}
workflows: ${{ steps.paths.outputs.workflows }}
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
fetch-depth: 0
persist-credentials: false
- name: Route the complete Git diff
id: paths
env:
BASE: ${{ github.event.pull_request.base.sha || github.event.before }}
run: |
git diff --check "$BASE" HEAD
# An edited router must not decide whether its own checks run.
git ls-tree "$BASE" -- tools/ci_changes.py > "$RUNNER_TEMP/ci-router-entry"
if [ -s "$RUNNER_TEMP/ci-router-entry" ]; then
git show "$BASE:tools/ci_changes.py" > "$RUNNER_TEMP/ci-router.py"
python3 "$RUNNER_TEMP/ci-router.py" --base "$BASE" >> "$GITHUB_OUTPUT"
else
# The initial installation has no base router: validate everything.
printf '%s\n' lua=true python=true package=true workflows=true >> "$GITHUB_OUTPUT"
fi

lua:
needs: changes
if: needs.changes.outputs.lua == 'true'
uses: ./.github/workflows/lua.yml

python:
needs: changes
if: needs.changes.outputs.python == 'true'
uses: ./.github/workflows/python.yml

package:
needs: changes
if: needs.changes.outputs.package == 'true'
uses: ./.github/workflows/package.yml

actionlint:
needs: changes
if: needs.changes.outputs.workflows == 'true'
uses: ./.github/workflows/workflows.yml
57 changes: 57 additions & 0 deletions .github/workflows/lua.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Lua

on:
workflow_call:

permissions:
contents: read

jobs:
lua:
runs-on: ubuntu-24.04
timeout-minutes: 5
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
fetch-depth: 0
persist-credentials: false
- name: Install Lua 5.2
run: |
sudo apt-get update -qq
sudo apt-get install --no-install-recommends -y lua5.2
- name: Test Lua file selection
run: >-
python3 tools/test_ci_changes.py
RoutingTests.test_lua_workflow_selects_type_changes
RoutingTests.test_lua_workflow_checks_option_like_names
- name: Select Lua files for this event
env:
BASE: ${{ github.event.pull_request.base.sha || github.event.before }}
run: |
mkdir -p .cache
git diff --check "$BASE" HEAD
# Enforce changed files on both events until the legacy baseline is done.
git diff --no-renames --name-only --diff-filter=ACMRT -z "$BASE" HEAD -- '*.lua' > .cache/ci-lua-files
- name: Check Lua syntax
run: |
luac5.2 -p .luacheckrc
xargs -0 -r -n1 luac5.2 -p -- < .cache/ci-lua-files
- name: Lint Lua
uses: lunarmodules/luacheck@cc089e3f65acdd1ef8716cc73a3eca24a6b845e4 # v1.2.0
with:
# This action runs args through sh. Parse the config even for an empty
# file list; pass filenames as NUL-delimited data, never shell source.
args: >-
--filename control.lua - < /dev/null &&
xargs -0 -r luacheck -- < .cache/ci-lua-files
- name: Install StyLua
uses: JohnnyMorganz/stylua-action@76fd70c03e6340ceaf673366712db9b20560b402 # v5
with:
token: ${{ github.token }}
version: v2.5.2
args: 'false'
- name: Check Lua formatting
run: |
# Parse the configuration even when only CI/configuration changed.
printf 'return true\n' | stylua --check --config-path .stylua.toml -
xargs -0 -r stylua --check --config-path .stylua.toml -- < .cache/ci-lua-files
30 changes: 30 additions & 0 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Package

on:
workflow_call:

permissions:
contents: read

jobs:
package:
runs-on: ubuntu-24.04
timeout-minutes: 3
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Build and validate the mod ZIP
run: |
python3 tools/package.py
python3 tools/validate_package.py
- name: Attach mod and checksum
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
with:
name: yuoki-${{ github.sha }}
overwrite: true
path: |
build/dist/*.zip
build/dist/SHA256SUMS
if-no-files-found: error
retention-days: 7
34 changes: 34 additions & 0 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Python

on:
workflow_call:

permissions:
contents: read

jobs:
python:
runs-on: ubuntu-24.04
timeout-minutes: 3
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Check Python syntax without executing game tests
run: |
python3 - <<'PY'
import ast
import subprocess
from pathlib import Path

files = subprocess.check_output(['git', 'ls-files', '-z', '*.py']).decode().split('\0')
for name in filter(None, files):
ast.parse(Path(name).read_bytes(), filename=name)
print('PASS', name)
PY
- name: Test CI change routing
run: python3 tools/test_ci_changes.py
- name: Test Pullfrog owner authorization
run: python3 tools/test_pullfrog_command.py
- name: Test package source boundaries
run: python3 tools/test_package.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,24 @@
name: Pullfrog checks
name: Workflows

# These checks validate the integration; they never launch the agent.
on:
pull_request:
paths:
- '.github/workflows/**'
- 'tools/pullfrog_command.py'
- 'tools/test_pullfrog_command.py'
push:
branches: [main]
paths:
- '.github/workflows/**'
- 'tools/pullfrog_command.py'
- 'tools/test_pullfrog_command.py'
workflow_call:

permissions:
contents: read

jobs:
validate:
actionlint:
runs-on: ubuntu-24.04
timeout-minutes: 5
timeout-minutes: 3
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Test owner command authorization
run: python3 tools/test_pullfrog_command.py
- name: Validate workflows
- name: Validate workflows with actionlint
env:
ACTIONLINT_VERSION: '1.7.12'
ACTIONLINT_VERSION: 1.7.12
run: |
curl --fail --location --silent --show-error \
curl --fail --silent --show-error --location --retry 3 \
"https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz" \
-o "$RUNNER_TEMP/actionlint.tar.gz"
echo "8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8 $RUNNER_TEMP/actionlint.tar.gz" |
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/build/
/.cache/

**/desktop.ini/
**/**/desktop.ini/
**/**/**/desktop.ini/
Expand Down Expand Up @@ -434,4 +437,4 @@ FodyWeavers.xsd
*.msp

# JetBrains Rider
*.sln.iml
*.sln.iml
45 changes: 45 additions & 0 deletions .luacheckrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
stds.factorio = {
read_globals = {
"defines", "log", "settings",
table = {fields = {deepcopy = {}}},
},
}
std = "lua52+factorio"
not_globals = {"io", "os", "dofile", "loadfile", "coroutine"}
max_line_length = false
exclude_files = {"build/**", ".cache/**"}

-- Factorio 2.0 data-stage helpers and intentional Yuoki cross-file exports.
local data_reads = {
"mods", "util", "kg", "sound_variations", "pipecoverspictures", "assembler2pipepictures", "assembler3pipepictures",
"circuit_connector_definitions", "default_circuit_wire_max_distance",
"make_rotated_animation_variations_from_sheet",
"yi", "yi_energy_usage_quality_multiplier", "blank_sprite",
"y_weapon_ztt", "y_laser2x2", "turret_gun1f12", "turret_gun2f12",
"turret_laser22f12", "turret_flame", "turret_plasma",
"playeranimations_y1", "playeranimations_y2", "playeranimations_y3", "playeranimations_y4",
"playeranimations_y5", "pipepictures_hv", "pipepictures_ec", "pipepictures_green",
}
files["data*.lua"].globals = {"data"}
files["data*.lua"].read_globals = data_reads
files["settings*.lua"].globals = {"data"}
files["prototypes/**"].globals = {"data"}
files["prototypes/**"].read_globals = data_reads
files["lib/yi-tools.lua"].globals = {"data", "yi", "yi_energy_usage_quality_multiplier", "blank_sprite"}
files["lib/yi-tools.lua"].read_globals = {"game", "prototypes"}

files["prototypes/entity/e_defense.lua"].globals = {"y_weapon_ztt", "y_laser2x2"}
files["prototypes/entity/e_defense_f12.lua"].globals = {"turret_gun1f12", "turret_gun2f12", "turret_laser22f12"}
files["prototypes/entity/e_pipes.lua"].globals = {"pipepictures_hv", "pipepictures_ec", "pipepictures_green"}
files["prototypes/objects/rie_turret_flame.lua"].globals = {"turret_flame"}
files["prototypes/objects/rie_turret_plasma.lua"].globals = {"turret_plasma"}
files["prototypes/objects/y_player_styles.lua"].globals = {
"playeranimations_y1", "playeranimations_y2", "playeranimations_y3", "playeranimations_y4", "playeranimations_y5",
}

files["control.lua"].globals = {"game", "storage"}
files["control.lua"].read_globals = {"script", "remote", "rendering", "prototypes", "helpers"}
files["scripts/**"].globals = {"game", "storage"}
files["scripts/**"].read_globals = {"script", "remote", "rendering", "prototypes", "helpers"}
files["migrations/**"].globals = {"game", "storage"}
files["migrations/**"].read_globals = {"script", "remote", "prototypes", "yi"}
5 changes: 5 additions & 0 deletions .stylua.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
syntax = "Lua52"
column_width = 120
indent_type = "Spaces"
indent_width = 2
quote_style = "AutoPreferDouble"
44 changes: 44 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Contributing

Search existing issues and pull requests for overlapping work, then use a topic
branch and a focused PR against the intended maintenance branch. Preserve
upstream attribution and [Licence.txt](Licence.txt). Do not bump `info.json`,
publish a release, or change gameplay as part of unrelated tooling work.

## Validation before commits and PR updates

Review every changed hunk and run `git diff --check` for every change. Run the
applicable checks below from the repository root before committing or pushing
a PR update; rerun affected checks after repairs. See
[development](docs/development.md) for the CI routing and tool versions.

- Lua: format each added or modified file with **StyLua 2.5.2** and the root
`.stylua.toml`, then check it with `luac5.2 -p`, **Luacheck 1.2.0** and
`stylua --check --config-path .stylua.toml`. Also syntax-check `.luacheckrc`.
Resolve warnings in touched files without blanket suppressions. Leave
untouched Lua files alone: the repository-wide baseline is deferred to
[issue #15](https://github.com/jatmn/Yuoki-Factorio-2.x/issues/15).
- Python/tools: parse tracked Python files without importing or executing game
code and run `python3 tools/test_ci_changes.py` plus
`python3 tools/test_pullfrog_command.py` and `python3 tools/test_package.py`.
- Workflows: run **actionlint 1.7.12**. Changes to the CI dispatcher or router
require all lightweight checks, including the Lua configuration probes.
- Shipped sources, metadata, locale, graphics, license notices or packaging
tools: run `python3 tools/package.py` and
`python3 tools/validate_package.py`. Inspect the intended ZIP contents.
- Documentation: verify links, commands and the resulting diff.

Lua CI currently checks changed files on both PRs and relevant pushes to `main`.
Formatting a touched file can create a mechanical diff within that file; keep
it separate from behavioral edits where practical. Do not reformat the whole
repository during ordinary contribution work.

Lightweight CI does not load Factorio. For gameplay and compatibility changes,
also validate with the supported Factorio version, relevant optional mods and
existing saves where affected. Report the exact versions, commands, results
and any untested engine or graphical behavior in the PR.

Use a Conventional Commit title, describe the problem and resulting behavior,
link related issues, and include validation results and limitations. Keep
credentials, local machine paths, game binaries, saves and build output out
of Git.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Yuoki Industries (Factorio 2.0)
Yuoki-Industries - a factorio mod by: [YuokiTani](https://mods.factorio.com/user/YuokiTani)

Currently Maintained by: [jatmn](https://mods.factorio.com/user/jatmn)
Currently Maintained by: [jatmn](https://mods.factorio.com/user/jatmn)

For contribution checks and local tooling, see [CONTRIBUTING.md](CONTRIBUTING.md)
and [development](docs/development.md).
Loading
Loading