Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove node_modules and compile typescript into minified scripts #2578

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

jsoref
Copy link
Contributor

@jsoref jsoref commented Nov 5, 2024

Merge / deployment checklist

  • Confirm this change is backwards compatible with existing workflows.
  • Confirm the readme has been updated if necessary.
  • Confirm the changelog has been updated if necessary.

@jsoref jsoref requested a review from a team as a code owner November 5, 2024 02:30
@jsoref
Copy link
Contributor Author

jsoref commented Nov 5, 2024

Before github/codeql-action@v3 6624720 (6s)

Fri, 01 Nov 2024 13:42:39 GMT Prepare all required actions
Fri, 01 Nov 2024 13:42:39 GMT Getting action download info
Fri, 01 Nov 2024 13:42:39 GMT Download action repository 'github/codeql-action@v3' (SHA:662472033e021d55d94146f66f6058822b0b39fd)
Fri, 01 Nov 2024 13:42:44 GMT Run ./.git/check-spelling-actions/upload-sarif
Fri, 01 Nov 2024 13:42:44 GMT Run github/codeql-action/upload-sarif@v3
Fri, 01 Nov 2024 13:42:44 GMT Uploading results
Fri, 01 Nov 2024 13:42:44 GMT   Processing sarif files: ["/tmp/tmp.yvZ4B9jZAF"]
Fri, 01 Nov 2024 13:42:44 GMT   Validating /tmp/tmp.yvZ4B9jZAF
Fri, 01 Nov 2024 13:42:44 GMT   Combining SARIF files using the CodeQL CLI
Fri, 01 Nov 2024 13:42:44 GMT   Adding fingerprints to SARIF file. See https://docs.github.com/en/enterprise-cloud@latest/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning#providing-data-to-track-code-scanning-alerts-across-runs for more information.
Fri, 01 Nov 2024 13:42:44 GMT   Uploading results
Fri, 01 Nov 2024 13:42:45 GMT   Successfully uploaded results

After check-spelling-sandbox/github-codeql-action@thin 3dc118c (2s)

Tue, 05 Nov 2024 13:22:18 GMT Prepare all required actions
Tue, 05 Nov 2024 13:22:18 GMT Getting action download info
Tue, 05 Nov 2024 13:22:18 GMT Download action repository 'check-spelling-sandbox/github-codeql-action@thin' (SHA:3dc118c13c28b2804932fce08b479e77e5007079)
Tue, 05 Nov 2024 13:22:19 GMT Run ./.git/check-spelling-actions/upload-sarif
Tue, 05 Nov 2024 13:22:19 GMT Run check-spelling-sandbox/github-codeql-action/upload-sarif@thin
Tue, 05 Nov 2024 13:22:20 GMT Uploading results
Tue, 05 Nov 2024 13:22:20 GMT   Processing sarif files: ["/tmp/tmp.CoFUHRgCYx"]
Tue, 05 Nov 2024 13:22:20 GMT   Validating /tmp/tmp.CoFUHRgCYx
Tue, 05 Nov 2024 13:22:20 GMT   Combining SARIF files using the CodeQL CLI
Tue, 05 Nov 2024 13:22:20 GMT   Adding fingerprints to SARIF file. See https://docs.github.com/en/enterprise-cloud@latest/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning#providing-data-to-track-code-scanning-alerts-across-runs for more information.
Tue, 05 Nov 2024 13:22:20 GMT   Uploading results
Tue, 05 Nov 2024 13:22:20 GMT   Successfully uploaded results

@aeisenberg
Copy link
Contributor

Thanks for your contribution. I appreciate the work you've put into this change. Before I can have a deeper look, there are some things I'd like to see:

  1. Please separate the spelling and other minor changes into a different PR.
  2. Can you explain why you need to add the upload/download artifact shims? We are not running these tests on GHES. We probably do need to update the remaining references to upload-artifact@v3, but I see no reason we need both.
  3. How does this change the development process? Do we need to run npm i && npm build before developing locally? CONTRIBUTING.md will need to be updated (but this can happen after we do a deeper review).

@jsoref jsoref mentioned this pull request Nov 6, 2024
3 tasks
@jsoref
Copy link
Contributor Author

jsoref commented Nov 6, 2024

  1. Please separate the spelling and other minor changes into a different PR.
    • Sure, I've spun up a check pass for this, but moved to Minor cleanup #2580 (note that it will have conflicts in one compiled action as MacOS is present in it)
  2. Can you explain why you need to add the upload/download artifact shims? We are not running these tests on GHES. We probably do need to update the remaining references to upload-artifact@v3, but I see no reason we need both.
    • The warnings/having v3 stuff come in were annoying and it looked like it mostly shouldn't be there. The idea that one can't properly upgrade a package so that everyone uses a single version of an action is a problem. I release an action that uses this action, and it's pretty crazy for me to have to think about actions that I use and potentially pull in two different versions just so that my action won't break if it's used in GHES (I don't have access to GHES, so I really don't know if it will break or not). -- Spirit moved to Upgrade workflows to actions/upload-artifact@v4 #2583
  3. How does this change the development process? Do we need to run npm i && npm build before developing locally?
    CONTRIBUTING.md will need to be updated (but this can happen after we do a deeper review).
    • There's a paragraph about not running npm install. The text about node_modules will need to be removed. I'm not actually sure about the general macOS bits. I built this on macOS and there's no sign of fsevents, so it's possible that the macOS only thing will no longer apply.
    • Yes, the text about not running npm install will need to change. I think it should generally suggest npm ci && npm run build instead of npm run build
    • Initial changes

@jsoref jsoref force-pushed the issue-2542 branch 2 times, most recently from 594f2e3 to fb48112 Compare November 7, 2024 01:07
@jsoref
Copy link
Contributor Author

jsoref commented Nov 7, 2024

That second item is mostly to deal with annoying things like:
https://github.com/check-spelling-sandbox/github-codeql-action/actions/runs/11717020444

Export file baseline information (windows-latest, nightly-latest)
The following actions use a deprecated Node.js version and will be forced to run on node20: actions/upload-artifact@v3. For more info: https://github.blog/changelog/2024-03-07-github-actions-all-actions-will-run-on-node20-instead-of-node16-by-default/
Export file baseline information (macos-latest, nightly-latest)
The following actions use a deprecated Node.js version and will be forced to run on node20: actions/upload-artifact@v3. For more info: https://github.blog/changelog/2024-03-07-github-actions-all-actions-will-run-on-node20-instead-of-node16-by-default/
Export file baseline information (ubuntu-latest, nightly-latest)
An error occurred when trying to refresh keys from hkp://keyserver.ubuntu.com: Error: The process '/usr/bin/gpg' failed with exit code 2
Export file baseline information (ubuntu-latest, nightly-latest)
An error occurred when trying to refresh keys from hkp://keyserver.ubuntu.com: Error: The process '/usr/bin/gpg' failed with exit code 2
Deprecation notice: v1, v2, and v3 of the artifact actions
The following artifacts were uploaded using a version of actions/upload-artifact that is scheduled for deprecation: "with-baseline-information-macos-latest-nightly-latest.sarif.json", "with-baseline-information-windows-latest-nightly-latest.sarif.json".
Please update your workflow to use v4 of the artifact actions.
Learn more: https://github.blog/changelog/2024-04-16-deprecation-notice-v3-of-the-artifact-actions/

Of which there were a lot. Anyway, the commit is currently nowhere. I can make a PR for it, or a simpler one that just upgrades. But the current state is #2046 (comment). I think someone (me?) may have merged and then had the upgrade reverted when someone realized it broke GHES, but it's too late in my day to find that item...

(In developing this PR, my goal was 0 errors and 0 warnings before opening it, which took a bit of poking.)

Copy link
Contributor

@aeisenberg aeisenberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks reasonable on the surface. I think this could work in general, but I need to discuss more with the rest of the team and try this out in various locations.

  • Can you update the .gitattributes file to include the new bundled files as linguist-generated=true?
  • The .github/workflows/update-dependencies.yml workflow can be removed.

Comment on lines +25 to +27
if command -v npm >/dev/null 2>/dev/null; then
npm ci
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the if necessary? If npm isn't available, how are we going to install dependencies?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for

- name: Prepare test
id: prepare-test
uses: ./.github/actions/prepare-test
with:
version: ${{ matrix.version }}
use-all-platform-bundle: 'false'
setup-kotlin: 'false'

because it uses an ubuntu:22.04 container that doesn't have npm:
container:
image: ubuntu:22.04

But it doesn't need node_modules for the magic that it's doing...

.github/workflows/pr-checks.yml Outdated Show resolved Hide resolved
Comment on lines +58 to +66
(
echo '*/*-action.js';
echo '*/*-action-post.js'
) >> .gitignore
for action in $(
find * -mindepth 1 -maxdepth 1 -type f -name action.yml
); do
git rm -f "$(dirname "$action")"/*-action*.js
done
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain why this is necessary as a comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can explain the problem here. I'm not entirely certain what the code is doing/trying to do.

The problem is that because we're bundling all the pieces from node_modules that we actually use as well as any dependency information, there's a segment in each of these files...

that looks like
{ Kie.exports = { name: "codeql", version: "3.27.1", private: !0, description: "CodeQL action", scripts: { build: "tsc --build && npm run package", package: "bash .github/workflows/script/package.sh", test: "ava src/**.test.ts --serial --verbose", "test-debug": "ava src/**.test.ts --serial --verbose --timeout=20m", lint: "eslint --report-unused-disable-directives --max-warnings=0 .", "lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix", "lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif" }, ava: { typescript: { rewritePaths: { "src/": "lib/" }, compile: !1 } }, license: "MIT", dependencies: { "@actions/artifact": "^2.1.9", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", "@actions/cache": "^3.2.4", "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^5.1.1", "@actions/glob": "^0.4.0", "@actions/io": "^1.1.3", "@actions/tool-cache": "^2.0.1", "@chrisgavin/safe-which": "^1.0.2", "@octokit/plugin-retry": "^5.0.2", "@octokit/types": "^13.6.1", "@schemastore/package": "0.0.10", "@types/node-forge": "^1.3.11", "@types/uuid": "^10.0.0", "adm-zip": "^0.5.16", "check-disk-space": "^3.4.0", "console-log-level": "^1.4.1", del: "^6.1.1", "fast-deep-equal": "^3.1.3", "file-url": "^3.0.0", "follow-redirects": "^1.15.9", fs: "0.0.1-security", "get-folder-size": "^2.0.1", "js-yaml": "^4.1.0", jsonschema: "1.4.1", long: "^5.2.3", "node-forge": "^1.3.1", path: "^0.12.7", semver: "^7.6.3", uuid: "^11.0.1", zlib: "^1.0.5" }, "//": ["micromatch is an unspecified dependency of ava"], devDependencies: { "@ava/typescript": "4.1.0", "@eslint/compat": "^1.1.1", "@eslint/eslintrc": "^3.1.0", "@eslint/js": "^9.13.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@types/adm-zip": "^0.5.5", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", "@types/get-folder-size": "^2.0.0", "@types/js-yaml": "^4.0.9", "@types/node": "20.9.0", "@types/semver": "^7.5.8", "@types/sinon": "^17.0.3", "@typescript-eslint/eslint-plugin": "^8.11.0", "@typescript-eslint/parser": "^8.11.0", ava: "^5.3.1", esbuild: "^0.24.0", eslint: "^8.57.1", "eslint-import-resolver-typescript": "^3.6.3", "eslint-plugin-filenames": "^1.3.2", "eslint-plugin-github": "^5.0.2", "eslint-plugin-import": "2.29.1", "eslint-plugin-no-async-foreach": "^0.1.1", micromatch: "4.0.8", nock: "^13.5.5", sinon: "^19.0.2", typescript: "^5.6.3" }, overrides: { "@actions/tool-cache": { semver: ">=6.3.1" }, "eslint-plugin-import": { semver: ">=6.3.1" }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" } } } })
reformatted as almost json
{ name: "codeql", version: "3.27.1", private: !0, description: "CodeQL action", scripts: { build: "tsc --build && npm run package", package: "bash .github/workflows/script/package.sh", test: "ava src/**.test.ts --serial --verbose",
    "test-debug": "ava src/**.test.ts --serial --verbose --timeout=20m", lint: "eslint --report-unused-disable-directives --max-warnings=0 .",
    "lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix",
    "lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif"
  }, ava: { typescript: { rewritePaths: {
        "src/": "lib/"
      }, compile: !1
    }
  }, license: "MIT", dependencies: {
    "@actions/artifact": "^2.1.9",
    "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2",
    "@actions/cache": "^3.2.4",
    "@actions/core": "^1.11.1",
    "@actions/exec": "^1.1.1",
    "@actions/github": "^5.1.1",
    "@actions/glob": "^0.4.0",
    "@actions/io": "^1.1.3",
    "@actions/tool-cache": "^2.0.1",
    "@chrisgavin/safe-which": "^1.0.2",
    "@octokit/plugin-retry": "^5.0.2",
    "@octokit/types": "^13.6.1",
    "@schemastore/package": "0.0.10",
    "@types/node-forge": "^1.3.11",
    "@types/uuid": "^10.0.0",
    "adm-zip": "^0.5.16",
    "check-disk-space": "^3.4.0",
    "console-log-level": "^1.4.1", del: "^6.1.1",
    "fast-deep-equal": "^3.1.3",
    "file-url": "^3.0.0",
    "follow-redirects": "^1.15.9", fs: "0.0.1-security",
    "get-folder-size": "^2.0.1",
    "js-yaml": "^4.1.0", jsonschema: "1.4.1", long: "^5.2.3",
    "node-forge": "^1.3.1", path: "^0.12.7", semver: "^7.6.3", uuid: "^11.0.1", zlib: "^1.0.5"
  },
  "//": [
    "micromatch is an unspecified dependency of ava"
  ], devDependencies: {
    "@ava/typescript": "4.1.0",
    "@eslint/compat": "^1.1.1",
    "@eslint/eslintrc": "^3.1.0",
    "@eslint/js": "^9.13.0",
    "@microsoft/eslint-formatter-sarif": "^3.1.0",
    "@types/adm-zip": "^0.5.5",
    "@types/console-log-level": "^1.4.5",
    "@types/follow-redirects": "^1.14.4",
    "@types/get-folder-size": "^2.0.0",
    "@types/js-yaml": "^4.0.9",
    "@types/node": "20.9.0",
    "@types/semver": "^7.5.8",
    "@types/sinon": "^17.0.3",
    "@typescript-eslint/eslint-plugin": "^8.11.0",
    "@typescript-eslint/parser": "^8.11.0", ava: "^5.3.1", esbuild: "^0.24.0", eslint: "^8.57.1",
    "eslint-import-resolver-typescript": "^3.6.3",
    "eslint-plugin-filenames": "^1.3.2",
    "eslint-plugin-github": "^5.0.2",
    "eslint-plugin-import": "2.29.1",
    "eslint-plugin-no-async-foreach": "^0.1.1", micromatch: "4.0.8", nock: "^13.5.5", sinon: "^19.0.2", typescript: "^5.6.3"
  }, overrides: {
    "@actions/tool-cache": { semver: ">=6.3.1"
    },
    "eslint-plugin-import": { semver: ">=6.3.1"
    },
    "eslint-plugin-jsx-a11y": { semver: ">=6.3.1"
    }
  }
}

Focussing just on the...

devDependencies
{
    "@ava/typescript": "4.1.0",
    "@eslint/compat": "^1.1.1",
    "@eslint/eslintrc": "^3.1.0",
    "@eslint/js": "^9.13.0",
    "@microsoft/eslint-formatter-sarif": "^3.1.0",
    "@types/adm-zip": "^0.5.5",
    "@types/console-log-level": "^1.4.5",
    "@types/follow-redirects": "^1.14.4",
    "@types/get-folder-size": "^2.0.0",
    "@types/js-yaml": "^4.0.9",
    "@types/node": "20.9.0",
    "@types/semver": "^7.5.8",
    "@types/sinon": "^17.0.3",
    "@typescript-eslint/eslint-plugin": "^8.11.0",
    "@typescript-eslint/parser": "^8.11.0", ava: "^5.3.1", esbuild: "^0.24.0", eslint: "^8.57.1",
    "eslint-import-resolver-typescript": "^3.6.3",
    "eslint-plugin-filenames": "^1.3.2",
    "eslint-plugin-github": "^5.0.2",
    "eslint-plugin-import": "2.29.1",
    "eslint-plugin-no-async-foreach": "^0.1.1", micromatch: "4.0.8", nock: "^13.5.5", sinon: "^19.0.2", typescript: "^5.6.3"
  }

... anyway, in there is this field:

    "@types/node": "20.9.0",

Which will be, by definition, different when we install a different version of @types/node.

Assuming all the code wants to know is "does this stuff compile", then the changes here are the steps required to make it happy. It basically removes the current versions of the files, adds them to ignore (because the check tool uses git porcelain to complain about any unknown or dirty files).

It's possible that this script could be simplified to do less checking, but it required a lot of thought just to understand why it was unhappy and how to make it happy, deciding whether it was still relevant was above my pay grade (you can see the same story with the removeNPMAbsolutePaths thing which I suspected wasn't necessary but wasn't confident about).

Note: the presence of the above blob makes each change annoying (as you will see when I refresh this branch with the location change to package.sh). If it's possible to remove the dependency information without breaking any code or legal requirements, I'd personally be inclined to do so. I'm not sure who's asking for it/why -- perhaps there's a contract that a library be able to inspect itself to determine which versions it thought it asked for? I don't really think that the app needs to know which build scripts were present in package.json.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHANGELOG.md Outdated Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
package.sh Outdated Show resolved Hide resolved
@aeisenberg
Copy link
Contributor

After you address the merge conflicts then I can run the tests again.

Also, in a separate PR, you can upgrade all of the references to *-artifact@v3 to @v4 in our workflows. These will need to change before @v3 is removed.

Instead of using a bundled node_modules,
* If `npm` isn't available (e.g. in a container), install it
* Run `npm install` before performing various tasks

Change pr-checks to not be particularly picky about the generated
content because it will differ between different versions as everything
is bundled together.

For review, the deletion of node_modules and lib will be in a distinct
commit.
This reduces the cost to download repository as an action.

This commit is logically part of the previous commit, but is split to
enable the preceding commit to be reviewed.
@jsoref
Copy link
Contributor Author

jsoref commented Nov 8, 2024

I hadn't thought through .github/workflows/update-dependencies.yml

It's referenced by:

>&2 echo "Failed: node_modules are not up to date. Add the 'Update dependencies' label to your PR to update them. Note it is important that node modules are updated on macOS and not any other operating system as there is one dependency (fsevents) that is needed for macOS and may not be installed if dependencies are updated on a Windows or Linux machine."

body.append(' - [ ] Remove and re-add the "Update dependencies" label to the PR to trigger just this workflow.')
body.append(' - [ ] Wait for the "Update dependencies" workflow to push a commit updating the dependencies.')

labels:
- Update dependencies

- [ ] Remove and re-add the "Update dependencies" label to the PR to trigger just this workflow.
- [ ] Wait for the "Update dependencies" workflow to push a commit updating the dependencies.

gh pr create \
--head "${NEW_BRANCH}" \
--base "${BASE_BRANCH}" \
--title "${pr_title}" \
--label "Update dependencies" \
--body "${pr_body}" \
--assignee "${GITHUB_ACTOR}" \
--draft

Thinking about what they're doing also gave me a headache. In the old world, updating dependencies involved committing all of the files in node_modules (and maybe committing lib??). In the new world, if you update package.json/package-lock.json then you need to update all of the actions (as managed by package.sh) which means someone somewhere still needs to do that.

For dependabot, that appeared as #2575 (comment)

I think that the same stuff still needs to exist, in that we would want a commit (for at least dependabot) that updates the bundled files.

I think what we want to do is to keep the workflow but change its work from committing the node_modules to committing the bundles see f73e1b6.

@jsoref
Copy link
Contributor Author

jsoref commented Nov 8, 2024

I've updated .gitattributes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Action takes 5-6 seconds to download
3 participants