Skip to content

[Bug]: Incremental builds: skipped projects re-publish Default-mode apps into ALL buildMode-specific artifacts #2337

Description

@thomari

AL-Go version

9.1

Describe the issue

In a multi-project repository where projects build multiple buildModes (via conditionalSettings with different artifact / preprocessorSymbols per mode), incremental builds (incrementalBuilds.onPush: true) corrupt the buildMode-specific artifacts of skipped projects: every buildMode artifact of a skipped project ends up containing the app that was built in Default mode.

Dependent projects that build a non-Default mode then download this wrong app as a project dependency from the baseline run and fail, e.g.:

AL1153 The referenced module 'X' with runtime reference version '17.0'
cannot be loaded by the compiler with version '16.0'.

Each incremental run becomes the baseline for the next one, so the wrong artifacts propagate until a full build happens.

Expected behavior

The skip-republish of a (project, buildMode) dimension should download the artifact of the same buildMode from the baseline run — e.g. pass the buildMode into DetermineBuildProject and use "$buildModePrefix$mask" masks (empty prefix for Default), analogous to how CalculateArtifactNames.ps1 builds the names.

Steps to reproduce

  1. Multi-project repo, useProjectDependencies: true, incrementalBuilds: { "onPush": true }.
  2. Project A with buildModes: ["Default", "X"] where mode X compiles against a different BC artifact (e.g. Default = BC28 sandbox, X = BC27.5), so the produced apps differ (different runtime).
  3. Project B depends on A (projectDependencies) and also builds mode X.
  4. Ensure one full green CICD run on main (baseline OK).
  5. Push a change that only modifies B.
  6. Inspect the artifacts of the incremental run: A-main-XApps-<version> contains the Default-built app (verify via the .app file name/version inside the zip).
  7. Any subsequent build of B in mode X (e.g. a PR) downloads A's poisoned X artifact from the baseline and fails with AL1153.

Additional context (logs, screenshots, etc.)

Root cause analysis

  1. _BuildALGoProject.yaml runs one job per (project, buildMode) matrix dimension, but the DetermineBuildProject step does not receive the buildMode input at all:

    - name: Determine whether to build project
      uses: microsoft/AL-Go-Actions/DetermineBuildProject@v9.1
      with:
        shell: ${{ inputs.shell }}
        skippedProjectsJson: ${{ inputs.skippedProjectsJson }}
        project: ${{ inputs.project }}
        baselineWorkflowRunId: ${{ inputs.baselineWorkflowRunId }}
  2. DetermineBuildProject.ps1 downloads the baseline artifacts of a skipped project with fixed masks — no buildMode prefix:

    foreach($mask in @('Apps','TestApps','Dependencies','PowerPlatformSolution')) {
        $artifact = GetArtifactsFromWorkflowRun ... -mask $mask -projects $project
  3. GetArtifactsFromWorkflowRun (Github-Helper.psm1) matches "$project-$branch-$mask-*". With mask Apps this only ever matches the Default artifact (<project>-<branch>-Apps-<version>) and never the buildMode-prefixed ones (<project>-<branch>-BC27-5Apps-<version>) that CalculateArtifactNames.ps1 produces. (The comment in the function — "Mask might include buildMode like TranslatedTestApps" — suggests callers are expected to pass buildMode-prefixed masks, but DetermineBuildProject doesn't.)

  4. The downloaded Default-mode content is then re-published under the current dimension's buildMode-prefixed artifact name (from CalculateArtifactNames): correct name, wrong content.

Workaround

incrementalBuilds: { "onPush": false } — full builds on push keep baselines correct while PR builds stay incremental (their project-dependency downloads then always come from a clean full-build baseline).

Metadata

Metadata

Labels

Fix ReadyFix ReadyIn PreviewCurrently available in AL-Go for GitHub previewbugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions