forked from smartcontractkit/chainlink
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[TT-1326] Update Solidty Foundry pipeline with Slither (smartcontract…
…kit#13986) * More univeral lcov prunning * update Shared code cov * exclude deleted files from Slither * use single source of truth for all Solidity Foundry jobs * fix json * compact output with jq * fix condition for fmt * try to scope tests to changes * move matrix check to step level * fix outputs path * trigger * test with Automation change * try with shared * run fmt also if any sol files were modified * fix job name in collect metrics * trigger pipeline only for localised change + update changes info * add changeset * remove test change * do not run forge fmt if shared contracts have changed * try artifact pipeline by hijacking hardhat * # This is a combination of 2 commits. # This is the 1st commit message: CR changes + test them # This is the commit message #2: use shell array * CR changes + test them use shell array init array CR changes + test them use shell array init array * remove test files * do not run Slither for test files * do not run fmt if test files were modified * remove unused config file * restore old Hardhat pipeline * add missing transmission setup * fix basic info condition, join 2 steps into 1, define higher-level coverage exclusions * define actions for installing Slither and solc-select * run all tests also if package.json changes; run them on all non_src changes * add action for validating whether all Slither reports and UML diagrams were generated * fetch origin in validation action * compare with HEAD in validate action * compare with origin in validation action * handle both csv and shell arrays in the validation action * update artifact pipeline with new actions * fix workflow after tests * fix how validation actions works with commits * treat shared as any other product * small fixes * apply CR changes * remove special handling for deleted files * remove apt-get update * use only dorny/paths * remove unused input * CR changes: use dorny/paths with quantifier, move scope validation to an action, remove whitespaces * fix workflow * fail bash scripts on erors * add set -euo pipefail to bash scripts * define action to detect foundry version * fix select solc version script, better slither report output * checkout repo * add id
- Loading branch information
Showing
18 changed files
with
1,354 additions
and
85 deletions.
There are no files selected for viewing
26 changes: 26 additions & 0 deletions
26
.github/actions/detect-solidity-foundry-version/action.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
name: 'Detect Foundry version in GNUmakefile' | ||
description: 'Detects Foundry version in GNUmakefile' | ||
inputs: | ||
working-directory: | ||
description: 'The GNUmakefile directory' | ||
required: false | ||
default: 'contracts' | ||
outputs: | ||
foundry-version: | ||
description: 'Foundry version found in GNUmakefile' | ||
value: ${{ steps.extract-foundry-version.outputs.foundry-version }} | ||
runs: | ||
using: 'composite' | ||
steps: | ||
- name: Extract Foundry version | ||
id: extract-foundry-version | ||
shell: bash | ||
working-directory: ${{ inputs.working-directory }} | ||
run: | | ||
foundry_version=$(grep -Eo "foundryup --version [^ ]+" GNUmakefile | awk '{print $3}') | ||
if [ -z "$foundry_version" ]; then | ||
echo "::error::Foundry version not found in GNUmakefile" | ||
exit 1 | ||
fi | ||
echo "Foundry version found: $foundry_version" | ||
echo "foundry-version=$foundry_version" >> $GITHUB_OUTPUT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
name: Setup Slither | ||
description: Installs Slither 0.10.3 for contract analysis. Requires Python 3.6 or higher. | ||
runs: | ||
using: composite | ||
steps: | ||
- name: Install Slither | ||
shell: bash | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install slither-analyzer==0.10.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
name: Setup Solc Select | ||
description: Installs Solc Select, required versions and selects the version to use. Requires Python 3.6 or higher. | ||
inputs: | ||
to_install: | ||
description: Comma-separated list of solc versions to install | ||
required: true | ||
to_use: | ||
description: Solc version to use | ||
required: true | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- name: Install solc-select and solc | ||
shell: bash | ||
run: | | ||
pip3 install solc-select | ||
sudo ln -s /usr/local/bin/solc-select /usr/bin/solc-select | ||
IFS=',' read -ra versions <<< "${{ inputs.to_install }}" | ||
for version in "${versions[@]}"; do | ||
solc-select install $version | ||
if [ $? -ne 0 ]; then | ||
echo "Failed to install Solc $version" | ||
exit 1 | ||
fi | ||
done | ||
solc-select install ${{ inputs.to_use }} | ||
solc-select use ${{ inputs.to_use }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
name: Validate Artifact Scope | ||
description: Checks there are any modified Solidity files outside of the specified scope. If so, it prints a warning message, but does not fail the workflow. | ||
inputs: | ||
product: | ||
description: The product for which the artifacts are being generated | ||
required: true | ||
sol_files: | ||
description: Comma-separated (CSV) or space-separated (shell) list of Solidity files to check | ||
required: true | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- name: Transform input array | ||
id: transform_input_array | ||
shell: bash | ||
run: | | ||
is_csv_format() { | ||
local input="$1" | ||
if [[ "$input" =~ "," ]]; then | ||
return 0 | ||
else | ||
return 1 | ||
fi | ||
} | ||
is_space_separated_string() { | ||
local input="$1" | ||
if [[ "$input" =~ ^[^[:space:]]+([[:space:]][^[:space:]]+)*$ ]]; then | ||
return 0 | ||
else | ||
return 1 | ||
fi | ||
} | ||
array="${{ inputs.sol_files }}" | ||
if is_csv_format "$array"; then | ||
echo "::debug::CSV format detected, nothing to do" | ||
echo "sol_files=$array" >> $GITHUB_OUTPUT | ||
exit 0 | ||
fi | ||
if is_space_separated_string "$array"; then | ||
echo "::debug::Space-separated format detected, converting to CSV" | ||
csv_array="${array// /,}" | ||
echo "sol_files=$csv_array" >> $GITHUB_OUTPUT | ||
exit 0 | ||
fi | ||
echo "::error::Invalid input format for sol_files. Please provide a comma-separated (CSV) or space-separated (shell) list of Solidity files" | ||
exit 1 | ||
- name: Check for changes outside of artifact scope | ||
shell: bash | ||
run: | | ||
echo "::debug::All modified contracts:" | ||
echo "${{ steps.transform_input_array.outputs.sol_files }}" | tr ',' '\n' | ||
if [ "${{ inputs.product }}" = "shared" ]; then | ||
excluded_paths_pattern="!/^contracts\/src\/v0\.8\/interfaces/ && !/^contracts\/src\/v0\.8\/${{ inputs.product }}/ && !/^contracts\/src\/v0\.8\/[^\/]+\.sol$/" | ||
else | ||
excluded_paths_pattern="!/^contracts\/src\/v0\.8\/${{ inputs.product }}/" | ||
fi | ||
echo "::debug::Excluded paths: $excluded_paths_pattern" | ||
unexpected_files=$(echo "${{ steps.transform_input_array.outputs.sol_files }}" | tr ',' '\n' | awk "$excluded_paths_pattern") | ||
missing_files="" | ||
set -e | ||
set -o pipefail | ||
if [[ -n "$unexpected_files" ]]; then | ||
products=() | ||
productsStr="" | ||
IFS=$'\n' read -r -d '' -a files <<< "$unexpected_files" || true | ||
echo "Files: ${files[@]}" | ||
for file in "${files[@]}"; do | ||
missing_files+="$file," | ||
product=$(echo "$file" | awk -F'src/v0.8/' '{if ($2 ~ /\//) print substr($2, 1, index($2, "/")-1); else print "shared"}') | ||
if [[ ! " ${products[@]} " =~ " ${product} " ]]; then | ||
products+=("$product") | ||
productsStr+="$product, " | ||
fi | ||
done | ||
productsStr=${productsStr%, } | ||
set +e | ||
set +o pipefail | ||
missing_files=$(echo $missing_files | tr ',' '\n') | ||
echo "Error: Found modified contracts outside of the expected scope: ${{ inputs.product }}" | ||
echo "Files:" | ||
echo "$missing_files" | ||
echo "Action required: If you want to generate artifacts for other products ($productsStr) run this workflow again with updated configuration" | ||
echo "# Warning!" >> $GITHUB_STEP_SUMMARY | ||
echo "## Reason: Found modified contracts outside of the expected scope: ${{ inputs.product }}" >> $GITHUB_STEP_SUMMARY | ||
echo "### Files:" >> $GITHUB_STEP_SUMMARY | ||
echo "$missing_files" >> $GITHUB_STEP_SUMMARY | ||
echo "## Action required: If you want to generate artifacts for other products ($productsStr) run this workflow again with updated configuration" >> $GITHUB_STEP_SUMMARY | ||
else | ||
echo "No unexpected files found." | ||
fi |
115 changes: 115 additions & 0 deletions
115
.github/actions/validate-solidity-artifacts/action.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
name: Validate Solidity Artifacts | ||
description: Checks whether Slither reports and UML diagrams were generated for all necessary files. If not, a warning is printed in job summary, but the job is not marked as failed. | ||
inputs: | ||
slither_reports_path: | ||
description: Path to the Slither reports directory (without trailing slash) | ||
required: true | ||
uml_diagrams_path: | ||
description: Path to the UML diagrams directory (without trailing slash) | ||
required: true | ||
validate_slither_reports: | ||
description: Whether Slither reports should be validated | ||
required: true | ||
validate_uml_diagrams: | ||
description: Whether UML diagrams should be validated | ||
required: true | ||
sol_files: | ||
description: Comma-separated (CSV) or space-separated (shell) list of Solidity files to check | ||
required: true | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- name: Transform input array | ||
id: transform_input_array | ||
shell: bash | ||
run: | | ||
is_csv_format() { | ||
local input="$1" | ||
if [[ "$input" =~ "," ]]; then | ||
return 0 | ||
else | ||
return 1 | ||
fi | ||
} | ||
is_space_separated_string() { | ||
local input="$1" | ||
if [[ "$input" =~ ^[^[:space:]]+([[:space:]][^[:space:]]+)*$ ]]; then | ||
return 0 | ||
else | ||
return 1 | ||
fi | ||
} | ||
array="${{ inputs.sol_files }}" | ||
if is_csv_format "$array"; then | ||
echo "::debug::CSV format detected, nothing to do" | ||
echo "sol_files=$array" >> $GITHUB_OUTPUT | ||
exit 0 | ||
fi | ||
if is_space_separated_string "$array"; then | ||
echo "::debug::Space-separated format detected, converting to CSV" | ||
csv_array="${array// /,}" | ||
echo "sol_files=$csv_array" >> $GITHUB_OUTPUT | ||
exit 0 | ||
fi | ||
echo "::error::Invalid input format for sol_files. Please provide a comma-separated (CSV) or space-separated (shell) list of Solidity files" | ||
exit 1 | ||
- name: Validate UML diagrams | ||
if: ${{ inputs.validate_uml_diagrams == 'true' }} | ||
shell: bash | ||
run: | | ||
echo "Validating UML diagrams" | ||
IFS=',' read -r -a modified_files <<< "${{ steps.transform_input_array.outputs.sol_files }}" | ||
missing_svgs=() | ||
for file in "${modified_files[@]}"; do | ||
svg_file="$(basename "${file%.sol}").svg" | ||
if [ ! -f "${{ inputs.uml_diagrams_path }}/$svg_file" ]; then | ||
echo "Error: UML diagram for $file not found" | ||
missing_svgs+=("$file") | ||
fi | ||
done | ||
if [ ${#missing_svgs[@]} -gt 0 ]; then | ||
echo "Error: Missing UML diagrams for files: ${missing_svgs[@]}" | ||
echo "# Warning!" >> $GITHUB_STEP_SUMMARY | ||
echo "## Reason: Missing UML diagrams for files:" >> $GITHUB_STEP_SUMMARY | ||
for file in "${missing_svgs[@]}"; do | ||
echo " $file" >> $GITHUB_STEP_SUMMARY | ||
done | ||
echo "## Action required: Please try to generate artifacts for them locally or using a different tool" >> $GITHUB_STEP_SUMMARY | ||
else | ||
echo "All UML diagrams generated successfully" | ||
fi | ||
- name: Validate Slither reports | ||
if: ${{ inputs.validate_slither_reports == 'true' }} | ||
shell: bash | ||
run: | | ||
echo "Validating Slither reports" | ||
IFS=',' read -r -a modified_files <<< "${{ steps.transform_input_array.outputs.sol_files }}" | ||
missing_reports=() | ||
for file in "${modified_files[@]}"; do | ||
report_file="$(basename "${file%.sol}")-slither-report.md" | ||
if [ ! -f "${{ inputs.slither_reports_path }}/$report_file" ]; then | ||
echo "Error: Slither report for $file not found" | ||
missing_reports+=("$file") | ||
fi | ||
done | ||
if [ ${#missing_reports[@]} -gt 0 ]; then | ||
echo "Error: Missing Slither reports for files: ${missing_reports[@]}" | ||
echo "# Warning!" >> $GITHUB_STEP_SUMMARY | ||
echo "## Reason: Missing Slither reports for files:" >> $GITHUB_STEP_SUMMARY | ||
for file in "${missing_reports[@]}"; do | ||
echo " $file" >> $GITHUB_STEP_SUMMARY | ||
done | ||
echo "## Action required: Please try to generate artifacts for them locally" >> $GITHUB_STEP_SUMMARY | ||
else | ||
echo "All Slither reports generated successfully" | ||
fi |
Oops, something went wrong.