diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..6f8d160
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,8 @@
+.git
+build/
+*.o
+.DS_Store
+._*
+__pycache__/
+*.pyc
+docs/
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 58ec01d..a3be7aa 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -5,7 +5,14 @@ on:
workflow_dispatch:
inputs:
sync_upstream:
+ description: 'Also check upstream_repo for new commits and sync if it changed'
required: false
+ type: boolean
+ default: false
+ all_arches:
+ description: 'Build every architecture, not just amd64'
+ required: false
+ type: boolean
default: false
debug_enabled:
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
@@ -13,27 +20,133 @@ on:
default: false
repository_dispatch:
- schedule:
- - cron: "0 */4 * * *" # min hour day week year
+ # NO schedule. This used to run `cron: "0 */4 * * *"` -- 6 times a day, ~180 runs a month --
+ # watching the upstream_repo submodule, which is rileytestut/AltServer-Windows, NOT this repo's
+ # upstream (NyaMisty/AltServer-Linux). AltServer-Windows has not moved since 071b1dd on
+ # 2022-04-25, so every one of those runs found nothing.
+ #
+ # Removed for a second and better reason than noise. When it DID find a commit it ran
+ # `git submodule update --remote -- upstream_repo` and built all four architectures from that
+ # newer source WITHOUT committing it, so a published artifact could come from code no commit in
+ # this repo describes. The build rewrites those sources textually
+ # (makefiles/rewrite_altserver_source.py), and that rewriter has no match guards at all, so an
+ # upstream move could change what the binary does with nothing failing -- see the TODO in
+ # REVIVAL.md. An unattended job is the worst place for that.
+ #
+ # Nothing is lost: the same check still runs on demand via the `sync_upstream` input above. The
+ # `github.event_name == 'schedule'` conditions in the check and matrix_setup jobs are left in
+ # place, so restoring the cron here is the only edit needed to bring the old behaviour back.
env:
REGISTRY: ghcr.io
jobs:
+ # Two guards for failures that were invisible while everything reported success. They live HERE,
+ # in the workflow with no paths: filter, because one of them detects a broken paths: filter --
+ # a guard inside build_image.yml would be skipped by exactly the bug it is meant to catch.
+ #
+ # Fast and dependency-free, so they gate nothing and cost nothing.
+ guards:
+ runs-on: ubuntu-latest
+ name: "Guards"
+ permissions:
+ contents: read
+ steps:
+ - uses: actions/checkout@v7
+
+ # An omitted paths: entry meant five commits of web fixes never reached a published image,
+ # while CI stayed green and the deployment kept serving the old code.
+ - name: Everything copied into the image triggers a rebuild
+ run: python3 tests/check_workflow_paths.py
+
+ # A literal newline inside a JS string literal once killed an entire ", re.DOTALL)
+
+
+def main():
+ node = shutil.which("node")
+ if node is None:
+ # In CI this is a hard failure: silently skipping is how the original bug shipped.
+ if os.environ.get("GITHUB_ACTIONS") == "true":
+ print("FAIL: node is not available on this runner, so the JS was never parsed.")
+ return 1
+ print("SKIP: node is not installed locally. CI will run this for real.")
+ return 0
+
+ import server # noqa: E402 -- path is set up above
+
+ pages = [
+ ("status page (PAGE)", server.PAGE),
+ ("pairing page (PAIRING_PAGE)", server.PAIRING_PAGE),
+ ("install page (INSTALL_PAGE)", server.INSTALL_PAGE),
+ ]
+
+ failures = 0
+ for name, html in pages:
+ blocks = SCRIPT_RE.findall(html)
+ if not blocks:
+ print("FAIL %s: no ", page, re.DOTALL))
+check(bool(js.strip()), "found the page's
+