vercel / ncc

Compile a Node.js project into a single file. Supports TypeScript, binary addons, dynamic requires.
https://npmjs.com/@vercel/ncc
MIT License
9.27k stars 291 forks source link

Add --check option, for CI #586

Open singingwolfboy opened 4 years ago

singingwolfboy commented 4 years ago

GitHub recommends ncc for building actions for GitHub Actions. When making a change to the repository for an existing action, it's very easy to forget to re-run ncc, so that the generated code is updated.

I would like to build an action that can verify that the code in the repository matches the generated code from ncc. To do that, it would be convenient to have a ncc --check option, which would compile the code in the repo, compare the result to the generated file that already exists, and exit with status code 0 if they match, or status code 1 if they do not match. This could be turned into an action to run on repositories for other actions, to make sure that code changes include regenerating the code.

fregante commented 4 years ago

What I do is call ncc && git diff --exit-code on CI:

https://github.com/fregante/title-to-labels-action/blob/dc5d5cb223e3a09f350b1f2daf81750ba728bc75/.github/workflows/build.yml#L14-L15

The command will throw and make the job error. Example


diff --git a/distribution/index.js b/distribution/index.js
index a6b0cef..c99c2c7 100644
--- a/distribution/index.js
+++ b/distribution/index.js
@@ -67,9 +67,7 @@ const execFile = util.promisify(__webpack_require__(129).execFile);
 async function init() {
    // Use ENV if it's a `push.tag` event
    if (process.env.GITHUB_REF.startsWith('refs/tags/')) {
-       const pushedTag = process.env.GITHUB_REF.replace('refs/tags/', '');
-       core.setOutput('version', process.env.GITHUB_REF.replace('refs/tags/', ''));
-       core.info('Run triggered by tag `' + pushedTag + '`. No new tags will be created by `daily-version-action`.');
+       const pushedTag = process.env.MY_REF.replace('refs/tags/', '');
        return;
    }

The good parts:

I even use it after prettier because prettier --check just tells you you forgot to run it.


Shameless self-plug: you can use ghat to add the workflow

npx ghat fregante/ghatemplates/is-dist-up-to-date
roryabraham commented 3 years ago

Before finding this issue, I used a script like this to rebuild the code with ncc and check for differences:

#!/bin/bash

declare -r GREEN='\033[0;32m'
declare -r RED='\033[0;31m'
declare -r NO_COLOR='\033[0m'

# Get a reference to the parent directory
# In order for the script to be runnable from anywhere, don't use relative path like '../'
declare -r PARENT_DIR=$(dirname "$(realpath "$0")")

# Get the list of Github Actions using ./listActions.sh
GITHUB_ACTIONS=( "$("$(dirname "$(realpath "$0")")/listActions.sh")" )

for ACTION in "${GITHUB_ACTIONS[@]}"; do
    # Build the action to a temp directory
    ACTION_DIR=$(dirname "$ACTION")
    ACTION_DIR_TEMP="$ACTION_DIR/temp"
    mkdir "$ACTION_DIR_TEMP"
    ncc build "$ACTION" -o "$ACTION_DIR_TEMP"

    cmp "$ACTION_DIR/index.js" "$ACTION_DIR_TEMP/index.js"

    # Make sure that the recompiled version of the file matches the pre-committed version
    if [[ $(cmp --silent "$ACTION_DIR/index.js" "$ACTION_DIR_TEMP/index.js") ]]; then
        echo -e "${GREEN}Success! Files are identical!${NO_COLOR}"
        rm -rf "$ACTION_DIR_TEMP"
        exit 0
    else
        echo -e "${RED}Error: Found difference between committed files and recompiled files.\n${NO_COLOR}Did you forget to run \`npm run gh-actions-build\`?"
        rm -rf "$ACTION_DIR_TEMP"
        exit 1
    fi
done

But I'm finding that it's not working, because there is a small diff between the output index.js file in the temp directory vs not. I'll try to do the same thing @fregante is doing with ncc && git diff --exit-code instead. It's much simpler than the script I had written...

roryabraham commented 3 years ago

Update: I've been using @fregante's method, but have recently run into an issue where the local path to my repo is included in the compiled output, causing a diff to appear.

Edit: This error was caused because one of my dependencies was internally using process.cwd, which ncc treats as a static value instead of a dynamic value. Overall I think that's not ideal because usually when using ncc for CI/CD we'd want process.cwd to be dynamically determined based on the machine that's running the script.

roryabraham commented 3 years ago

Also, I just discovered that ncc will have a different output if run on a windows machine vs a unix machine (was the same on macOS and ubuntu, but different on windows).

isilher commented 1 year ago

Update: I've been using @fregante's method, but have recently run into an issue where the local path to my repo is included in the compiled output, causing a diff to appear.

Edit: This error was caused because one of my dependencies was internally using process.cwd, which ncc treats as a static value instead of a dynamic value. Overall I think that's not ideal because usually when using ncc for CI/CD we'd want process.cwd to be dynamically determined based on the machine that's running the script.

@roryabraham I'm running into exactly this issue now, did you ever find a way to work around this?