ci: check crates (#29009)

* init

* print all errors in the end

* print success msg

* use skip patterns instead of specific file

* v2

* checkout full history

* install toml cli in Github Actions step

* git diff only list added and modified

* prevent empty owner list

* lint: ident with space 2

* update 404 hint

* lint

Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com>

* wording

Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com>

* indent with space

* add some friendly error message

* wording

Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com>

* Update .github/workflows/crate-check.yml

Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com>

* fix indent

Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com>
This commit is contained in:
Yihau Chen 2022-12-12 11:51:37 +08:00 committed by GitHub
parent 88a8f40bd2
commit 254d3f20b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 175 additions and 0 deletions

52
.github/workflows/crate-check.yml vendored Normal file
View File

@ -0,0 +1,52 @@
name: crate-check
on:
push:
branches:
- master
pull_request:
branches:
- master
paths:
- "**/Cargo.toml"
- ".github/workflows/crate-check.yml"
jobs:
check:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get commit range (push)
if: ${{ github.event_name == 'push' }}
run: |
echo "COMMIT_RANGE=$GITHUB_SHA" >> $GITHUB_ENV
- name: Get commit range (pull_request)
if: ${{ github.event_name == 'pull_request' }}
run: |
echo "COMMIT_RANGE=${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV
- name: Setup Rust
shell: bash
run: |
source ci/rust-version.sh stable
rustup default $rust_stable
- name: Install toml-cli
shell: bash
run: |
cargo install toml-cli
- run: |
ci/check-crates.sh
error_reporting:
needs:
- check
if: failure() && github.event_name == 'push'
uses: ./.github/workflows/error-reporting.yml
secrets:
WEBHOOK: ${{ secrets.SLACK_ERROR_REPORTING_WEBHOOK }}

123
ci/check-crates.sh Executable file
View File

@ -0,0 +1,123 @@
#!/usr/bin/env bash
# input:
# env:
# - CRATE_TOKEN
# - COMMIT_RANGE
if [[ -z $COMMIT_RANGE ]]; then
echo "COMMIT_RANGE should be provided"
exit 1
fi
if ! command -v toml &>/dev/null; then
echo "not found toml-cli"
cargo install toml-cli
fi
declare skip_patterns=(
"Cargo.toml"
"programs/sbf"
)
declare -A verified_crate_owners=(
["solana-grimes"]=1
)
# get Cargo.toml from git diff
readarray -t files <<<"$(git diff "$COMMIT_RANGE" --diff-filter=AM --name-only | grep Cargo.toml)"
printf "%s\n" "${files[@]}"
error_count=0
for file in "${files[@]}"; do
read -r crate_name package_publish workspace < <(toml get "$file" . | jq -r '(.package.name | tostring)+" "+(.package.publish | tostring)+" "+(.workspace | tostring)')
echo "=== $crate_name ($file) ==="
if [[ $package_publish = 'false' ]]; then
echo -e "⏩ skip (package_publish: $package_publish)\n"
continue
fi
if [[ "$workspace" != "null" ]]; then
echo -e "⏩ skip (is a workspace root)\n"
continue
fi
for skip_pattern in "${skip_patterns[@]}"; do
if [[ $file =~ ^$skip_pattern ]]; then
echo -e "⏩ skip (match skip patterns)\n"
continue 2
fi
done
result="$(cargo owner --list -q "$crate_name" --token "$CRATE_TOKEN" 2>&1)"
if [[ $result =~ ^error ]]; then
if [[ $result == *"Not Found"* ]]; then
((error_count++))
echo "❌ new crate $crate_name not found on crates.io. you can either
1. mark it as not for publication in its Cargo.toml
[package]
...
publish = false
or
2. make a dummy publication with these steps:
a. Create a empty crate locally with this template
[package]
name = \"<PACKAGE_NAME>\"
version = \"0.0.1\"
description = \"<PACKAGE_DESC>\"
authors = [\"Solana Maintainers <maintainers@solana.foundation>\"]
repository = \"https://github.com/solana-labs/solana\"
license = \"Apache-2.0\"
homepage = \"https://solana.com/\"
documentation = \"https://docs.rs/<PACKAGE_NAME>\"
edition = \"2021\"
b. cargo publish --token <GRIMES_CRATES_IO_TOKEN>
"
else
((error_count++))
echo "$result"
fi
else
readarray -t owners <<<"$result"
verified_owner_count=0
unverified_owner_count=0
for owner in "${owners[@]}"; do
if [[ -z $owner ]]; then
continue
fi
owner_id="$(echo "$owner" | awk '{print $1}')"
if [[ ${verified_crate_owners[$owner_id]} ]]; then
((verified_owner_count++))
echo "$owner"
else
((unverified_owner_count++))
echo "$owner"
fi
done
if [[ ($unverified_owner_count -gt 0) ]]; then
((error_count++))
echo "error: found unverified owner(s)"
elif [[ ($verified_owner_count -le 0) ]]; then
((error_count++))
echo "error: there are no verified owners"
fi
fi
echo ""
done
if [ "$error_count" -eq 0 ]; then
echo "success"
exit 0
else
exit 1
fi