diff --git a/.github/workflows/release_crates.yaml b/.github/workflows/release_crates.yaml index ee915caa..4953d306 100644 --- a/.github/workflows/release_crates.yaml +++ b/.github/workflows/release_crates.yaml @@ -1,15 +1,17 @@ name: Publish Rust Crates on: - pull_request: push: branches: - main - - ci/release jobs: publish: runs-on: ubuntu-latest + environment: release + permissions: + id-token: write # Required for OIDC token exchange with crates.io + steps: - name: Checkout repository uses: actions/checkout@v4 @@ -17,80 +19,43 @@ jobs: - name: Set up Rust uses: dtolnay/rust-toolchain@stable - - name: Install cargo-binstall - run: curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash - - - name: Install tq - run: cargo binstall -y tomlq - - name: Cache Cargo registry and index - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git - key: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }} - restore-keys: cargo-${{ runner.os }}- - - - name: Login to crates.io - if: github.event_name == 'push' - run: cargo login ${{ secrets.CRATES_API_TOKEN }} + key: cargo-publish-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }} + restore-keys: cargo-publish-${{ runner.os }}- - - name: Write resolved versions to file - run: | - jq -r '.packages[] | select(.source == null) | "\(.name) \(.version)"' < <(cargo metadata --format-version=1) > resolved_versions.txt + - name: Authenticate with crates.io (Trusted Publishing) + uses: rust-lang/crates-io-auth-action@v1 + id: auth - - - name: Publish Crates + - name: Publish crates + env: + CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} run: | - ROOT_VERSION=$(tq -f Cargo.toml .package.version | sed 's/"//g') - for manifest in crates/types/Cargo.toml crates/core/Cargo.toml crates/db/Cargo.toml crates/gql/Cargo.toml crates/subgraph/Cargo.toml crates/studio/Cargo.toml; do - if [ -f "$manifest" ]; then - echo "Checking $manifest for changes..." - - CRATE_NAME=$(tq -f "$manifest" .package.name | sed 's/"//g') # remove quotes around package name - VERSION=$(tq -f "$manifest" .package.version) - # if VERSION is { workspace = true }, use the root version - if [ "$VERSION" = "{ workspace = true }" ]; then - VERSION="$ROOT_VERSION" - fi - - if cargo search -q "$CRATE_NAME" | grep "$VERSION"; then - echo "$CRATE_NAME ($manifest) is already published with version $VERSION, skipping..." - continue - fi + CRATES="surfpool-types surfpool-db surfpool-subgraph surfpool-gql surfpool-core surfpool-studio-ui" - # Resolve dependencies - while IFS= read -r dep; do - DEP_NAME=$(echo "$dep" | awk '{print $1}') - RESOLVED_VERSION=$(echo "$dep" | awk '{print $2}') + for CRATE in $CRATES; do + VERSION=$(cargo metadata --format-version=1 --no-deps \ + | jq -r --arg name "$CRATE" '.packages[] | select(.name == $name) | .version') - # Check if resolved version exists on crates.io - if cargo search -q "$DEP_NAME" --limit 1 | grep -q "$RESOLVED_VERSION"; then - FINAL_VERSION="$RESOLVED_VERSION" - else - # Get the latest published version from crates.io - FINAL_VERSION=$(cargo search -q "$DEP_NAME" | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+' | head -1) - echo "Resolved version $RESOLVED_VERSION for $DEP_NAME is not published. Using latest published version $FINAL_VERSION instead." - fi - - # Replace workspace dependencies with the determined version - sed -i "s|${DEP_NAME} = { workspace = true }|${DEP_NAME} = \"$FINAL_VERSION\"|" "$manifest" - sed -i "s|${DEP_NAME} = { workspace = true, default-features = false }|${DEP_NAME} = \"$FINAL_VERSION\"|" "$manifest" - sed -i "s|${DEP_NAME} = { path = \"../types\" }|${DEP_NAME} = \"$FINAL_VERSION\"|" "$manifest" + if [ -z "$VERSION" ]; then + echo "::warning::Could not find version for $CRATE, skipping" + continue + fi - done < resolved_versions.txt + PUBLISHED=$(cargo search "$CRATE" --limit 1 2>/dev/null \ + | grep "^${CRATE} " | sed 's/.*"\(.*\)".*/\1/' || true) - echo "Publishing $CRATE_NAME from $manifest..." - if [ "${{ github.event_name }}" = "pull_request" ]; then - cargo publish --package $CRATE_NAME --dry-run --allow-dirty - else - cargo publish --package $CRATE_NAME --allow-dirty - fi - else - echo "Skipping $manifest, Cargo.toml not found." + if [ "$PUBLISHED" = "$VERSION" ]; then + echo "$CRATE@$VERSION is already published, skipping" + continue fi - done - env: - CRATES_API_TOKEN: ${{ secrets.CRATES_API_TOKEN }} + echo "Publishing $CRATE@$VERSION..." + cargo publish --package "$CRATE" + sleep 15 + done