Skip to content

Grunt issue: Files flagged as stale despite identical SHA1 hashes #350

@mona-shakiba

Description

@mona-shakiba

Issue Description
I'm encountering an issue with moodle-plugin-ci's Grunt task on GitHub Actions. It's flagging JavaScript files as "stale and needs to be rebuilt" even though they are byte-for-byte identical when manually rebuilt with the exact same toolchain in the CI environment.
The issue only occurs when AMD modules import that import some dependencies, like Moodle core modules. If I use moodle-plugin-ci locally on my moodle server, It does not show any notification for Stale files. But on the moodle-plugin-ci (exactly same version as on my moodle server) installed on github action server, flags files as stale.

Environment Information

  • GitHub Actions environment:

moodle-plugin-ci: ^4 (4.5.7)
Node.js: v22.14.0
npm: 10.9.2
grunt-cli: v1.4.3
grunt: v1.6.1
rollup: v4.39.0
OS: Ubuntu 22.04

  • My Moodle server:

moodle-plugin-ci: ^4 (4.5.7)
Node.js: v22.14.0
npm: 10.9.2
grunt-cli: v1.4.3
grunt: v1.6.1
rollup: v4.39.0
OS: Debian GNU/Linux 12 (bookworm)

Inconsistent Behavior

Simple AMD modules with no imports work fine in both environments
AMD modules that import modules (like 'core/notification') are flagged as stale
On my Moodle server (4.5), when I run npx grunt amd followed by moodle-plugin-ci grunt --max-lint-warnings 0 local/shopping_cart, it succeeds with no "stale" warnings
When I commit these same built files and push them, the GitHub Actions workflow fails, flagging the files as stale
If I modify my workflow to rebuild the AMD module files right before running moodle-plugin-ci grunt --max-lint-warnings 0, then the check passes with no issues

Steps to Reproduce

1- Clone a Moodle plugin (in my case moodle-local_shopping_cart)
2- Your javascript file should have an import command.
3- Build JavaScript files locally with the same toolchain as CI
4- Commit the built files and push
5- Run CI with moodle-plugin-ci
6- See files flagged as stale despite being identical

Current Behavior

The moodle-plugin-ci grunt command flags files as stale with errors like:

File is stale and needs to be rebuilt: amd/build/address.min.js
File is stale and needs to be rebuilt: amd/build/address.min.js.map

Expected Behavior

Since the files are identical when rebuilt in the CI environment, they should not be flagged as stale.

Minimal Reproduction Case
I've isolated the issue to a simple test case:

A basic JavaScript file with no imports works fine:

javascript/**
 * [Description for init]
 *
 * @return [type]
 *
 */
function init() {
    // eslint-disable-next-line no-console
    console.log('my log');
}

init();

The same file with a Moodle core import triggers the "stale" error:

/**
 * [Description for init]
 *
 * @return [type]
 *
 */
import Notification from 'core/notification';

function init() {
    // eslint-disable-next-line no-console
    console.log('my log');
}

init();

export const showNotification = (message, type) => {
    // eslint-disable-next-line no-console
    console.log(message, type);
    Notification.alert('Hello!', 'Welcome to my site!', 'Continue');
};

Evidence

I've added debugging steps to verify the files are identical:

I manually rebuilt the files in the CI environment using npx grunt --gruntfile=../moodle/Gruntfile.js amd
I compared SHA1 hashes of the original files and the rebuilt files:

=== ORIGINAL FILE HASHES ===
7dfdabc29955398f8dae97d2bc510d72587cbf70  amd/build/address.min.js
17965e81e33853e0662871c9306a14685b5c64bd  amd/build/address.min.js.map

=== REBUILT FILE HASHES ===
7dfdabc29955398f8dae97d2bc510d72587cbf70  amd/build/address.min.js
17965e81e33853e0662871c9306a14685b5c64bd  amd/build/address.min.js.map

When I run moodle-plugin-ci grunt immediately after manually rebuilding, it passes with no stale file warnings
But when run as part of the normal CI workflow, it fails with stale file warnings

Task Logs

  • "Grunt" task log:
Run # Load NVM and use the version from .nvmrc
Found '/home/runner/work/moodle-local_shopping_cart/moodle-local_shopping_cart/moodle/.nvmrc' with version <lts/jod>
Now using node v22.14.0 (npm v10.9.2)
/home/runner/work/moodle-local_shopping_cart/moodle-local_shopping_cart
=== Collecting Environment Information ===
Current directory: /home/runner/work/moodle-local_shopping_cart/moodle-local_shopping_cart
=== ENVIRONMENT INFO ===
Current directory: /home/runner/work/moodle-local_shopping_cart/moodle-local_shopping_cart
Node.js version: v22.14.0
NPM version: 10.9.2
Grunt version: grunt-cli v1.4.3
grunt v1.6.1
Rollup version: rollup v4.39.0
Running moodle-plugin-ci grunt from directory: /home/runner/work/moodle-local_shopping_cart/moodle-local_shopping_cart
 RUN  Grunt on local_shopping_cart
>> Running tasks for component directory local/shopping_cart

Running "ignorefiles" task

Running "eslint:amd" (eslint) task
Browserslist: caniuse-lite is outdated. Please run:
  npx browserslist@latest --update-db
  Why you should do it regularly: https://github.com/browserslist/browserslist#browsers-data-updating

Running "rollup:dist" (rollup) task

Done.
Running "gherkinlint" task

Done.
>> Running tasks for component directory local/shopping_cart

Running "stylelint:css" (stylelint) task
>> Linted 1 files without errors

Done.
File is stale and needs to be rebuilt: amd/build/menu.min.js.map
File is stale and needs to be rebuilt: amd/build/cashier.min.js.map
File is stale and needs to be rebuilt: amd/build/shistory.min.js.map
File is stale and needs to be rebuilt: amd/build/address.min.js
File is stale and needs to be rebuilt: amd/build/address.min.js.map
File is stale and needs to be rebuilt: amd/build/cashout.min.js.map
File is stale and needs to be rebuilt: amd/build/cashier.min.js
File is stale and needs to be rebuilt: amd/build/form_users_selector.min.js.map
File is stale and needs to be rebuilt: amd/build/cashier_modal.min.js.map
File is stale and needs to be rebuilt: amd/build/checkout_manager.min.js
File is stale and needs to be rebuilt: amd/build/cart.min.js.map
File is stale and needs to be rebuilt: amd/build/checkout_manager.min.js.map
File is stale and needs to be rebuilt: amd/build/cashier_modal.min.js
File is stale and needs to be rebuilt: amd/build/notifications.min.js.map
Error: Process completed with exit code 1.

  • "Debug stale file detection" task log:
Run # Load NVM and use the version from .nvmrc
/home/runner/work/moodle-local_shopping_cart/moodle-local_shopping_cart
Found '/home/runner/work/moodle-local_shopping_cart/moodle-local_shopping_cart/moodle/.nvmrc' with version <lts/jod>
Now using node v22.14.0 (npm v10.9.2)
/home/runner/work/moodle-local_shopping_cart/moodle-local_shopping_cart/plugin
=== STARTING FILE DIFFERENCE DETECTION ===
=== BUILD ENVIRONMENT ===
v22.14.0
10.9.2
grunt-cli v1.4.3
grunt v1.6.1
grunt-cli v1.4.3
grunt v1.6.1
rollup v4.39.0
=== BACKING UP ORIGINAL BUILT FILES ===
Backed up: amd/build/menu.min.js.map
Backed up: amd/build/cashier.min.js.map
Backed up: amd/build/menu.min.js
Backed up: amd/build/shistory.min.js.map
Backed up: amd/build/address.min.js
Backed up: amd/build/address.min.js.map
Backed up: amd/build/cashout.min.js.map
Backed up: amd/build/cashier.min.js
Backed up: amd/build/form_users_selector.min.js.map
Backed up: amd/build/cart.min.js
Backed up: amd/build/cashier_modal.min.js.map
Backed up: amd/build/checkout_manager.min.js
Backed up: amd/build/cart.min.js.map
Backed up: amd/build/notifications.min.js
Backed up: amd/build/shistory.min.js
Backed up: amd/build/cashout.min.js
Backed up: amd/build/checkout_manager.min.js.map
Backed up: amd/build/form_users_selector.min.js
Backed up: amd/build/cashier_modal.min.js
Backed up: amd/build/notifications.min.js.map
=== ORIGINAL FILE HASHES ===
b34359aaa26b48ecb88c3b1b823e1339ca5590e6  amd/build/menu.min.js.map
d580d3430982343007d7f071ebb7b4746694f3d8  amd/build/cashier.min.js.map
2276047dc1169147f489c5b7e54c39da4b23b1ab  amd/build/menu.min.js
ddfb3b107a7f8759a954f39ce31e723936a961cb  amd/build/shistory.min.js.map
7dfdabc29955398f8dae97d2bc510d72587cbf70  amd/build/address.min.js
17965e81e33853e0662871c9306a14685b5c64bd  amd/build/address.min.js.map
c25f0eb66866c90bf8bc4fbb11a1036a80d5b74b  amd/build/cashout.min.js.map
9aa60bff35ed6c0ff499806a85841f684d823bf6  amd/build/cashier.min.js
f54172cc76f0b9f34a978fcf46d1f16571e029bb  amd/build/form_users_selector.min.js.map
34415a02a705e4c390df98d5432b5a79af97e02c  amd/build/cart.min.js
1986047319c487da2f7bf7e48fe232cae0c53880  amd/build/cashier_modal.min.js.map
286c2ce857846be133158076779155de55122ff5  amd/build/checkout_manager.min.js
382662f957d2e643e2ab816cf5b4bdcd71273974  amd/build/cart.min.js.map
ea0ee34e89a3bfc815ecca077444111de96f0dbd  amd/build/notifications.min.js
375f5f8d1d3ec1c1729863922732457c14ff3769  amd/build/shistory.min.js
8f90a41c44f4540d52a3dd731c8bf3f15b3b3a7f  amd/build/cashout.min.js
e47b78a685dc18cb71b51a15acc9d03b550daffd  amd/build/checkout_manager.min.js.map
c10a6195d20962c914fff24942f8f7ffd3827a0f  amd/build/form_users_selector.min.js
8061350e10ee998e9c7dec09faebdccd650e6dc0  amd/build/cashier_modal.min.js
070b239d1bd5b933d81ca7ef333a511ffe253c26  amd/build/notifications.min.js.map
=== REBUILDING FILES ===
Running "ignorefiles" task
Running "eslint:amd" (eslint) task
Browserslist: caniuse-lite is outdated. Please run:
  npx browserslist@latest --update-db
  Why you should do it regularly: https://github.com/browserslist/browserslist#browsers-data-updating
Running "rollup:dist" (rollup) task
Done.
=== REBUILT FILE HASHES ===
b34359aaa26b48ecb88c3b1b823e1339ca5590e6  amd/build/menu.min.js.map
d580d3430982343007d7f071ebb7b4746694f3d8  amd/build/cashier.min.js.map
2276047dc1169147f489c5b7e54c39da4b23b1ab  amd/build/menu.min.js
ddfb3b107a7f8759a954f39ce31e723936a961cb  amd/build/shistory.min.js.map
7dfdabc29955398f8dae97d2bc510d72587cbf70  amd/build/address.min.js
17965e81e33853e0662871c9306a14685b5c64bd  amd/build/address.min.js.map
c25f0eb66866c90bf8bc4fbb11a1036a80d5b74b  amd/build/cashout.min.js.map
9aa60bff35ed6c0ff499806a85841f684d823bf6  amd/build/cashier.min.js
f54172cc76f0b9f34a978fcf46d1f16571e029bb  amd/build/form_users_selector.min.js.map
34415a02a705e4c390df98d5432b5a79af97e02c  amd/build/cart.min.js
1986047319c487da2f7bf7e48fe232cae0c53880  amd/build/cashier_modal.min.js.map
286c2ce857846be133158076779155de55122ff5  amd/build/checkout_manager.min.js
382662f957d2e643e2ab816cf5b4bdcd71273974  amd/build/cart.min.js.map
ea0ee34e89a3bfc815ecca077444111de96f0dbd  amd/build/notifications.min.js
375f5f8d1d3ec1c1729863922732457c14ff3769  amd/build/shistory.min.js
8f90a41c44f4540d52a3dd731c8bf3f15b3b3a7f  amd/build/cashout.min.js
e47b78a685dc18cb71b51a15acc9d03b550daffd  amd/build/checkout_manager.min.js.map
c10a6195d20962c914fff24942f8f7ffd3827a0f  amd/build/form_users_selector.min.js
8061350e10ee998e9c7dec09faebdccd650e6dc0  amd/build/cashier_modal.min.js
070b239d1bd5b933d81ca7ef333a511ffe253c26  amd/build/notifications.min.js.map
=== COMPARING FILE HASHES ===
All file hashes match - this is unexpected since they're flagged as stale
=== DETAILED BINARY COMPARISON OF SAMPLE FILE ===
No different files found for detailed analysis
=== RUNNING OFFICIAL GRUNT CHECK ===
 RUN  Grunt on local_shopping_cart
>> Running tasks for component directory local/shopping_cart
Running "ignorefiles" task
Running "eslint:amd" (eslint) task
Browserslist: caniuse-lite is outdated. Please run:
  npx browserslist@latest --update-db
  Why you should do it regularly: https://github.com/browserslist/browserslist#browsers-data-updating
Running "rollup:dist" (rollup) task
Done.
Running "gherkinlint" task
Done.
>> Running tasks for component directory local/shopping_cart
Running "stylelint:css" (stylelint) task
>> Linted 1 files without errors
Done.

Analysis
The evidence shows that:

  • The SHA1 hashes are identical when comparing original and rebuilt files in the CI environment
  • When running the grunt check immediately after rebuilding (either on moodle server, or on github action server) , no stale files are reported
  • When running the grunt check as part of the normal workflow on github action server, stale files are reported
  • The issue only occurs with files that import some dependencies, like Moodle core modules

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions