Skip to content

H-3684: Upgrade to Yarn 4 #12477

H-3684: Upgrade to Yarn 4

H-3684: Upgrade to Yarn 4 #12477

Workflow file for this run

name: Lint
on:
pull_request:
push:
branches:
- main
merge_group:
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: hashintel
TURBO_REMOTE_ONLY: true
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
setup:
runs-on: ubuntu-24.04
outputs:
packages: ${{ steps.packages.outputs.packages }}
steps:
- name: Checkout source code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 2
- name: Enable corepack
uses: ./.github/actions/enable-corepack
- name: Install turbo
uses: ./.github/actions/install-turbo
- name: Determine changed packages
id: packages
run: |
FILTER=$(turbo run lint --dry-run=json --filter '...[HEAD^]' | jq -e '.packages | contains(["//"])' > /dev/null && echo '' || echo '--filter ...[HEAD^]')
PACKAGES=$(sh -c "turbo run lint --dry-run=json $FILTER" \
| jq '.tasks[]' \
| jq 'select(.task == "lint")' \
| jq --compact-output --slurp '{ package: [.[].package] | unique, include: [( .[] | {package: .package, directory: .directory })] | unique }')
echo "packages=$PACKAGES" | tee -a $GITHUB_OUTPUT
package:
name: Package
needs: [setup]
strategy:
matrix: ${{ fromJSON(needs.setup.outputs.packages) }}
fail-fast: false
if: needs.setup.outputs.packages != '{"package":[],"include":[]}'
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 2
- name: Enable corepack
uses: ./.github/actions/enable-corepack
- name: Install turbo
uses: ./.github/actions/install-turbo
- name: Find lint steps to run
id: lints
run: |
set -x
ESLINT=$(turbo run lint:eslint --filter '${{ matrix.package }}' --dry-run=json \
| jq '[.tasks[] | select(.task == "lint:eslint" and .command != "<NONEXISTENT>")] != []' || echo 'false')
echo "eslint=$ESLINT" | tee -a $GITHUB_OUTPUT
TSC=$(turbo run lint:tsc --filter '${{ matrix.package }}' --dry-run=json \
| jq '[.tasks[] | select(.task == "lint:tsc" and .command != "<NONEXISTENT>")] != []' || echo 'false')
echo "tsc=$TSC" | tee -a $GITHUB_OUTPUT
CODEGEN=$(turbo run codegen --filter '${{ matrix.package }}' --dry-run=json \
| jq '[.tasks[] | select(.task == "codegen" and .command != "<NONEXISTENT>")] != []' || echo 'false')
echo "codegen=$CODEGEN" | tee -a $GITHUB_OUTPUT
HAS_RUST=$([[ -f "${{ matrix.directory }}/Cargo.toml" || ${{ matrix.directory }} = "apps/hash-graph" ]] && echo 'true' || echo 'false')
echo "has-rust=$HAS_RUST" | tee -a $GITHUB_OUTPUT
if [[ $HAS_RUST = 'true' ]]; then
if [[ -f "${{ matrix.directory }}/rust-toolchain.toml" ]]; then
RUST_TOOLCHAIN_FILE="${{ matrix.directory }}/rust-toolchain.toml"
else
RUST_TOOLCHAIN_FILE="rust-toolchain.toml"
fi
echo "rust-toolchain=$(yq '.toolchain.channel' $RUST_TOOLCHAIN_FILE)" | tee -a $GITHUB_OUTPUT
echo "has-rustfmt=$(yq '.toolchain.components | contains(["rustfmt"])' $RUST_TOOLCHAIN_FILE)" | tee -a $GITHUB_OUTPUT
echo "has-clippy=$(yq '.toolchain.components | contains(["clippy"])' $RUST_TOOLCHAIN_FILE)" | tee -a $GITHUB_OUTPUT
fi
- name: Prune repository
uses: ./.github/actions/prune-repository
with:
scope: ${{ matrix.package }}
- name: Install Protobuf
if: always() && steps.lints.outputs.has-rust == 'true'
run: sudo apt install protobuf-compiler
- name: Install Rust toolchain
if: always() && steps.lints.outputs.has-rust == 'true'
uses: ./.github/actions/install-rust-toolchain
with:
toolchain: ${{ steps.lints.outputs.rust-toolchain }}
working-directory: ${{ matrix.directory }}
- name: Install Rust tools
if: always() && steps.lints.outputs.has-rust == 'true'
uses: taiki-e/install-action@6da51af62171044932d435033daa70a0eb3383ba # v2.45.6
with:
tool: [email protected],[email protected],[email protected],[email protected]
- name: Warm up repository
uses: ./.github/actions/warm-up-repo
- name: Cache Rust dependencies
if: always() && steps.lints.outputs.has-rust == 'true'
uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2.7.5
with:
workspaces: ${{ matrix.directory }}
save-if: ${{ !startsWith(github.ref, 'refs/heads/gh-readonly-queue') }}
- name: Show disk usage
run: df -h
- name: Run codegen
if: always() && steps.lints.outputs.codegen == 'true'
run: |
set -o pipefail
turbo run codegen --force --filter "${{ matrix.package }}"
while IFS= read -r line; do
if [[ -n "$line" ]]; then
echo "Checking diff of ${{ matrix.directory }}/$line"
git --no-pager diff --exit-code --color -- "${{ matrix.directory }}/$line"
fi
done <<< "$(cat ${{ matrix.directory }}/turbo.json | grep -v '^ *//' | jq -r '.pipeline.codegen.outputs | if . == null then "." else .[] end')"
- name: Show disk usage
run: df -h
- name: Run ESLint
if: always() && steps.lints.outputs.eslint == 'true'
run: turbo run lint:eslint --filter "${{ matrix.package }}"
- name: Run TSC
if: always() && steps.lints.outputs.tsc == 'true'
run: turbo run lint:tsc --filter "${{ matrix.package }}"
- name: Run rustfmt
if: always() && steps.lints.outputs.has-rustfmt == 'true'
working-directory: ${{ matrix.directory }}
run: just format --check
- name: Run clippy
if: always() && steps.lints.outputs.has-clippy == 'true'
run: |
pushd ${{ matrix.directory }}
just clippy --message-format=json \
| clippy-sarif \
| jq '.runs[].results |= unique' \
> clippy.sarif
popd
cat ${{ matrix.directory }}/clippy.sarif | sarif-fmt
jq -e '.runs[].results == []' ${{ matrix.directory }}/clippy.sarif> /dev/null
- name: Print clippy errors to summary
if: failure() && steps.lints.outputs.has-clippy == 'true'
run: |
echo '```' >> $GITHUB_STEP_SUMMARY
cat ${{ matrix.directory }}/clippy.sarif | sarif-fmt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
if: always() && steps.lints.outputs.has-clippy == 'true'
with:
sarif_file: ${{ matrix.directory }}/clippy.sarif
category: ${{ matrix.package }}
- name: Check public documentation
if: always() && steps.lints.outputs.has-rust == 'true'
working-directory: ${{ matrix.directory }}
env:
RUSTDOCFLAGS: "--check -Z unstable-options -D warnings"
run: cargo doc --all-features --no-deps -Zrustdoc-scrape-examples
- name: Check private documentation
if: always() && steps.lints.outputs.has-rust == 'true'
working-directory: ${{ matrix.directory }}
env:
RUSTDOCFLAGS: "--check -Z unstable-options -D warnings"
run: cargo doc --all-features --no-deps -Zrustdoc-scrape-examples --document-private-items
- name: Show disk usage
run: df -h
global:
name: Global
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Warm up repository
uses: ./.github/actions/warm-up-repo
- name: Validate package.json generated from Cargo.toml
if: ${{ success() || failure() }}
run: |
cargo -Zscript run --manifest-path ".github/scripts/rust/sync-turborepo.rs" . | xargs yarn prettier --write >/dev/null
git --no-pager diff --exit-code --color '**/package.json'
- name: Run yarn lint:dependency-version-consistency
if: ${{ success() || failure() }}
run: |
if ! yarn lint:dependency-version-consistency; then
echo ''
echo ''
echo 'ℹ️ ℹ️ ℹ️'
echo 'Try running `yarn fix:dependency-version-consistency` locally to apply autofixes.'
echo 'ℹ️ ℹ️ ℹ️'
exit 1
fi
- name: Run yarn lint:lockfile-lint
if: ${{ success() || failure() }}
run: |
if ! yarn lint:lockfile-lint; then
echo ''
echo ''
echo 'ℹ️ ℹ️ ℹ️'
echo 'Try resetting yarn.lock to its previous state and then run `yarn install`.'
echo 'If your `~/.npmrc` mentions a custom registry, you should remove this setting first.'
echo 'ℹ️ ℹ️ ℹ️'
exit 1
fi
- name: Run yarn lint:license-in-workspaces
if: ${{ success() || failure() }}
env:
FORCE_COLOR: "1" ## https://www.npmjs.com/package/chalk#supportsColor
run: |
if ! yarn lint:license-in-workspaces; then
echo ''
echo ''
echo 'ℹ️ ℹ️ ℹ️'
echo 'Please fix the above errors locally for the check to pass.'
echo 'If you don’t see them, try merging target branch into yours.'
echo 'ℹ️ ℹ️ ℹ️'
exit 1
fi
- name: Run yarn lint:markdownlint
if: ${{ success() || failure() }}
run: |
if ! yarn lint:markdownlint; then
echo ''
echo ''
echo 'ℹ️ ℹ️ ℹ️'
echo 'Try running `yarn fix:markdownlint` locally to apply autofixes.'
echo 'ℹ️ ℹ️ ℹ️'
exit 1
fi
- name: Run yarn lint:prettier
if: ${{ success() || failure() }}
run: |
if ! yarn lint:prettier; then
echo ''
echo ''
echo 'ℹ️ ℹ️ ℹ️'
echo 'Try running `yarn fix:prettier` locally to apply autofixes.'
echo 'ℹ️ ℹ️ ℹ️'
exit 1
fi
- name: Run yarn lint:taplo
if: ${{ success() || failure() }}
run: |
if ! yarn lint:taplo; then
echo ''
echo ''
echo 'ℹ️ ℹ️ ℹ️'
echo 'Try running `yarn fix:taplo` locally to apply autofixes.'
echo 'ℹ️ ℹ️ ℹ️'
exit 1
fi
## TODO: Replace with `yarn fix:yarn-dedupe` after upgrading to Yarn v3+
## https://yarnpkg.com/cli/dedupe
## https://github.com/yarnpkg/berry/issues/2297
- name: Run yarn lint:yarn-deduplicate
if: ${{ success() || failure() }}
run: |
if ! yarn lint:yarn-deduplicate; then
echo ''
echo ''
echo 'ℹ️ ℹ️ ℹ️'
echo 'Some dependencies can be deduplicated, which will make node_modules'
echo 'lighter and potentially save us from unexplainable bugs.'
echo 'Please run `yarn fix:yarn-deduplicate` locally and commit yarn.lock.'
echo 'You may need to run the command 2-3 times in some rare cases.'
echo 'ℹ️ ℹ️ ℹ️'
exit 1
fi
## yarn --frozen-lockfile does not work for monorepos, so using a workaround:
## https://github.com/yarnpkg/yarn/issues/5840#issuecomment-467516207
## TODO: Use `yarn install --immutable` after upgrading to Yarn v3+
- name: Check yarn.lock stability
if: ${{ success() || failure() }}
run: |
git diff yarn.lock
if ! git diff --exit-code yarn.lock; then
echo ''
echo ''
echo 'ℹ️ ℹ️ ℹ️'
echo 'Changes were detected in yarn.lock file after running `yarn install`.'
echo 'This makes runtime less stable, so should be avoided.'
echo 'Please run `yarn install` locally and commit yarn.lock.'
echo 'You may also want to run `yarn fix:yarn-deduplicate` just in case.'
echo 'ℹ️ ℹ️ ℹ️'
exit 1;
fi
- name: Validate renovate config
if: ${{ success() || failure() }}
run: |
# Adding renovate in `package.json` causes incompatibility between our dependencies and their dependencies.
npm install --global renovate
if ! renovate-config-validator; then
echo ''
echo ''
echo 'ℹ️ ℹ️ ℹ️'
echo 'Please fix the above errors locally for the check to pass.'
echo 'If you don’t see them, try merging target branch into yours.'
echo 'ℹ️ ℹ️ ℹ️'
exit 1
fi
passed:
name: Linting passed
needs: [setup, package, global]
if: always()
runs-on: ubuntu-latest
steps:
- name: Check setup script
run: |
[[ ${{ needs.setup.result }} = success ]]
- name: Check package results
run: |
[[ ${{ needs.package.result }} =~ success|skipped ]]
- name: Check global results
run: |
[[ ${{ needs.global.result }} =~ success|skipped ]]
- name: Notify Slack on failure
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
if: ${{ failure() && github.event_name == 'merge_group' }}
env:
SLACK_LINK_NAMES: true
SLACK_MESSAGE: "At least one linting job failed for a Pull Request in the Merge Queue failed <@U0143NL4GMP> <@U02NLJY0FGX>" # Notifies C & T
SLACK_TITLE: Linting failed
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_USERNAME: GitHub
VAULT_ADDR: ""
VAULT_TOKEN: ""