Skip to content
This repository has been archived by the owner on Jan 25, 2023. It is now read-only.

fix: fix the builds for public projects that use yarn 2 (or above) with workspaces #763

Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 44 additions & 5 deletions run-build-functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,21 @@ install_deps() {
restore_node_modules() {
local workspace_output
local workspace_exit_code
local workspace_errors_logfile
local workspace_error_message
local package_manager_version
local package_locations
local installer=$1
# YARN_IGNORE_PATH will ignore the presence of a local yarn executable (i.e. yarn 2) and default
# to using the global one (which, for now, is always yarn 1.x). See https://yarnpkg.com/configuration/yarnrc#ignorePath
# we can actually use this command for npm workspaces as well
workspace_output="$(YARN_IGNORE_PATH=1 yarn workspaces --json info 2>/dev/null)"
workspace_errors_logfile="yarn-workspace-errors-log.json"
workspace_output="$(YARN_IGNORE_PATH=1 yarn workspaces --json info 2>"$workspace_errors_logfile")"
workspace_exit_code=$?

if [ $workspace_exit_code -eq 0 ]
then
echo "$installer workspaces detected"
local package_locations
# Extract all the packages and respective locations. .data will be a JSON object like
# .data will be a JSON object like
# {
# "my-package-1": {
# "location": "packages/blog-1",
Expand All @@ -109,7 +113,42 @@ restore_node_modules() {
# (...)
# }
# We need to cache all the node_module dirs, or we'll always be installing them on each run
mapfile -t package_locations <<< "$(echo "$workspace_output" | jq -r '.data | fromjson | to_entries | .[].value.location')"
mapfile -t package_locations <<<"$(echo "$workspace_output" | jq -r '.data | fromjson | to_entries | .[].value.location')"
else
# In yarn 1.x workspaces only work on private repos.
# See https://classic.yarnpkg.com/lang/en/docs/workspaces/#toc-how-to-use-it
# we have to check the error message to see if the repo is public and uses
# yarn 2 (or greater) with workspaces
if [ $workspace_exit_code -eq 1 ]
then
workspace_error_message=$(jq -r ".data" "$workspace_errors_logfile" 2>/dev/null)
package_manager_version=$(yarn --version)
if [ "${package_manager_version:0:1}" -gt 1 ] && [ "$workspace_error_message" = "Workspaces can only be enabled in private projects." ]
Copy link
Contributor

Choose a reason for hiding this comment

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

Since we know the installer up ahead and we can check for yarn's version (similar to what we're doing in here already) I was thinking we could simplify things here a bit and not require us to check the error logs of the first command execution? We could instead check:

  • if the installer is yarn and we're using version greater than 1, run the remainder of this then block
  • else run the YARN_IGNORE_PATH=1 block.

Something like (nvm the chaos and indentation):

local package_manager_version
package_manager_version=$(yarn --version)

if [ "$installer" = "yarn"] && [ "${package_manager_version:0:1}" -gt 1 ]
then
  # the yarn berry workspaces logic
  (...)
else
  (...)
  workspace_output="$(YARN_IGNORE_PATH=1 yarn workspaces --json info 2>/dev/null)"
  (etc.)
fi
# Handle the output of the executions above
if [ ${#package_locations[@]} -ne 0 ]
  then
    echo "$installer workspaces detected"
    # Extract all the packages and respective locations.
    restore_js_workspaces_cache "${package_locations[@]}"
  else
    echo "No $installer workspaces detected"

Copy link
Author

@fulopkovacs fulopkovacs May 31, 2022

Choose a reason for hiding this comment

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

@JGAntunes Hey 👋,

sorry for replying 4 days late, I forgot about this issue... 😅 Your suggestion seems to be reasonable, I'd be happy to try it and add add a test this week, if that's okay for you (tbh I might have to work on it on the weekend, because currently it doesn't fit into our schedule at work).

Copy link
Contributor

Choose a reason for hiding this comment

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

@fulopkovacs sure thing, however works better for you 👍 again, apologies for taking so long to follow up.

then
# From yarn 2 there's no way to output information about repo's workspaces
# in pure json. Here's how the output of `yarn workspaces list --json` looks like
# (stringified json objects separated with new lines):
#
# ```
# {"location":".","name":"the-monorepo"}
# {"location":"packages/blog-1","name":"dev blog"}
# {"location":"packages/blog-2","name":"personal blog"}
# ```
workspace_output=[$(paste -s -d ',' <(yarn workspaces list --json 2>/dev/null))]
workspace_exit_code=$?

if [ $workspace_exit_code -eq 0 ]
then
mapfile -t package_locations <<<"$(jq -r '.[].location | select(. != ".")' <<<"$workspace_output")"
fi
fi
fi
fi

if [ ${#package_locations[@]} -ne 0 ]
then
echo "$installer workspaces detected"
# Extract all the packages and respective locations.
restore_js_workspaces_cache "${package_locations[@]}"
else
echo "No $installer workspaces detected"
Expand Down