Weekly Recap: August 14-21

Two posts went out on their own this week: I Can Turn Off My Code. I Can’t Turn Off Yours. on the 18th, making the case that whether a trigger needs to run shouldn’t be a compile-time guess when the platform can answer that question itself at runtime, and AL Runner v2.2 and v2.3 on the 20th, covering coverage reporting, inline execute, and a watch mode that stopped lying to you mid-save. Here’s everything else that happened across repos this week.

AL Runner: one fix after the dust settled, and a growing case for a second post

That AL Runner post covered everything through v2.3.1 on August 19, so I won’t repeat it here. One thing shipped right after it went out: releases now gate on the test suite instead of pushing the release commit and tag before tests finish running. A failed release used to leave a dead git tag sitting on main — which is exactly what had just happened twice in a row the week before, so this closes a real gap, not a theoretical one.

Underneath all of that, the companion AL Language Tests suite kept growing — 13 more merged PRs in this window alone, pinning down xmlport imports, event dispatch inside precompiled base app pages, and NavApp.GetCurrentModuleInfo in a boolean context. Last week I flagged this repo as a candidate for its own dedicated post instead of a recap footnote. That’s now two weeks running, and the case has only gotten stronger: it’s the sandbox-verified answer key every AL Runner fix ultimately has to match against real BC, and on its own it’s shipping PRs at a pace most of my other repos would be happy with.

The Linux fast lane met a second repo, and a second repo found real bugs

The build-dimension array that ProtectEmptyBuildDimensions hands back gets called inline as a hashtable-literal value in Get-ProjectsToBuild, and on Windows PowerShell 5.1 — the shell the Initialization job actually runs in — that shape serializes through ConvertTo-Json as {"value":[...],"Count":N} instead of a plain array. strategy.matrix.include can’t iterate that, so Build/BuildLinux jobs just never spawn: no error, no skipped-job entry, nothing in the run, while PostProcess still marks the whole thing failed. That had been silently breaking every CI/CD and pull request run on both AL-Go-PTE and AL-Go-AppSource since August 14, not just the narrow case the original commit was aimed at. I couldn’t reproduce the exact broken JSON locally — no Windows PowerShell 5.1 box on hand — so the fix is built on strong circumstantial evidence (the timing lines up exactly, and the shape matches a known PS5.1 ConvertTo-Json quirk) backed by a new regression test that checks the actual JSON round-trip instead of just the in-memory object, since the object looks fine on every PowerShell version and only the serialized string doesn’t.

The other two fixes came out of onboarding a second repo onto the fast lane. Dependency resolution runs Install-NonMicrosoftDependenciesFromNuGet across parallel worker runspaces, but the trusted-feeds object gets built once and shared by reference across all of them — and BcContainerHelper’s own feed-decoration code uses a check-then-Add-Member guard that isn’t thread-safe, so two workers racing it could both pass the check and one would crash with a duplicate-member error, taking an AppSource dependency down with it. The fix pre-populates those properties once, before any worker exists, so the racy guard never has anything left to do. Separately, a compile-only build that never creates a container was still running the container-cleanup step unconditionally, which shells out to docker ps and fails outright when Docker was never started — now skipped under the same guard the build step already uses. Alongside those, three small commits to the bc-test-from-source workflow closed out supporting bugs: multi-app compiles not staging sibling apps for each other, an artifact-staging directory starting with a dot so upload-artifact silently ignored everything in it, and compiled apps keeping their committed version forever so BC’s deploy step never saw them as newer than what was already installed.

A 677-commit-stale fork, and a dependency landmine it was hiding

bc-code-atlas’s AL support sits on a forked branch of Christian Hovenbitzer’s graphify-al, and that fork had gone stale — no sync with upstream since June 23, 677 commits behind. I caught it up this week, and it wasn’t a mechanical merge. Upstream had split the old monolithic extraction function into a proper extractors/ package partway through those 677 commits, and two AL-specific behaviors — table/tableextension key nodes, member-qualified trigger anchoring — had been quietly hooked directly into the old function with no documentation anywhere pointing at them. Deleting that function in favor of upstream’s new structure would have silently dropped both. I only caught it by running the full AL test suite, tracing the failures back to source, and re-porting both behaviors into a local override for whoever does the next sync (graphify-al#62 ).

The sync also dragged in a tree-sitter-al 4.0 upgrade, which broke query-join parsing outright — the new grammar restructured how DataItemLink gets parsed, dropping the wrapper my join-edge code was reading through, so joins silently stopped resolving. I fixed the parser for the new shape and pinned the dependency to >=4.0.0,<5.0.0 (graphify-al#63 ) instead of leaving it floating — the old pin was unbounded and had only stayed safe by accident, since the lockfile happened to still hold 3.0.1 while PyPI had already moved to 4.0.1. Anyone resolving fresh would have hit the same silent breakage with no error at all. Both fixes went upstream into Christian’s repo, not just into my own fork, and then bc-code-atlas fast-forwarded onto the fixed tip with zero local reconciliation needed (bc-code-atlas#57 ). Separately, the registry resolver’s tests against the live upstream BC mirror drifted again as new w1-28.1.* builds landed — the fourth time that’s happened — so I refreshed the hardcoded assertions to match (bc-code-atlas#56 ).

A couple of smaller things

The script that migrates old webinar write-ups into WordPress for areopa-academy/webinar-blog hit three separate WordPress API quirks in one sitting: a 500 from the tags endpoint that wasn’t wrapped in the same retry the categories loop already had, a UnicodeEncodeError from a Cyrillic image filename landing raw in a Content-Disposition header, and six old post.json files using a date-only string where WordPress’s REST API wants a full ISO 8601 datetime. All three got fixed the same day .

I also merged a community PR into vsc-lintercop , my VS Code extension for BusinessCentral.LinterCop, adding an in-editor deprecation notice and a README banner pointing people at ALCops. LinterCop itself is reaching end-of-life once AL Language v18 ships around October, and Arthur van de Vondervoort put together the migration nudge so users find out from the extension itself instead of the hard way. Thanks, Arthur.