It's Fred

1337

Vercel Private Submodules Workaround

June 24, 2020 (last updated August 30, 2021) - 2 min read

Vercel (formerly Zeit) does not support private submodules for Github-based deploys, but there is a workaround.

Support of private submodules in Vercel GitHub-based builds has remained an open feature request since 2017.

An example of how to workaround this, using an example repository with a single submodule follows:

  1. Save the following as vercel-submodule-workaround.sh in your project directory, adjusting MAIN_REPO, SUBMODULE_PATH and SUBMODULE_REF as necessary.

    # repo paths (supplied without the protocol prefix)
    MAIN_REPO=github.com/foo/my-repo.git
    
    # the reference of the submodule in .gitmodules (usually the path)
    SUBMODULE_REF=my/submodule/path
    
    if [ "$VERCEL_GIT_COMMIT_SHA" == "" ]; then
      echo "Error: VERCEL_GIT_COMMIT_SHA is empty"
      exit 1
    fi
    
    if [ "$GITHUB_ACCESS_TOKEN" == "" ]; then
      echo "Error: GITHUB_ACCESS_TOKEN is empty"
      exit 1
    fi
    
    # stop script execution on error
    set -e
    
    # set up an empty temporary work directory
    rm -rf vercel-tmp || true
    mkdir vercel-tmp
    cd vercel-tmp
    
    # checkout the current commit
    git init
    git remote add origin https://$GITHUB_ACCESS_TOKEN@$MAIN_REPO
    git fetch --depth=1 origin $VERCEL_GIT_COMMIT_SHA
    git checkout $VERCEL_GIT_COMMIT_SHA
    
    # set the submodule repo paths to ones that vercel can access
    mv .gitmodules .gitmodules.original
    cat .gitmodules.original | sed "s/git@github.com:/https:\/\/$GITHUB_ACCESS_TOKEN@github.com\//" > .gitmodules
    
    # checkout the submodule
    git submodule sync
    git submodule update --init --recursive 2>&1 | sed "s/$GITHUB_ACCESS_TOKEN/\*\*\*\*/"
    
    # move the submodule to where it should have been if vercel had supported submodules
    cd ..
    rm -rf vercel-tmp/$SUBMODULE_PATH/.git
    if [ -d $SUBMODULE_PATH ]; then
    mv $SUBMODULE_PATH $SUBMODULE_PATH.original
    fi
    mkdir -p $(dirname $SUBMODULE_PATH)
    mv vercel-tmp/$SUBMODULE_PATH/ $SUBMODULE_PATH
    
    # show contents of submodule path in logs
    ls -l $SUBMODULE_PATH
    
    # clean up
    rm -rf vercel-tmp
  2. Go to your project’s settings page, then Environment Variables in Vercel and enable the option Automatically expose System Environment Variables.

  3. Generate a personal GitHub access token with the “repo” privileged. Save it as a (secret if you want) environment variable called GITHUB_ACCESS_TOKEN using your project’s settings page. Be careful not to include spaces/newlines before or after the token.

  4. Add the following command to your project’s package.json:

    "vercel-build": "./vercel-submodule-workaround.sh && npm run build",
  5. Override the build command that Vercel uses to npm run vercel-build

(This blog uses submodules and is deployed via Vercel GitHub-based builds using the above workaround)


Fred

Fred is a Nordic software engineer who once set out never to blog in his life, but then thought better of it. You should follow him on Twitter