Skip to content

feat: add dry-run transaction contract #41

feat: add dry-run transaction contract

feat: add dry-run transaction contract #41

Workflow file for this run

name: Release
on:
push:
branches:
- main
- '**'
paths:
- Cargo.toml
- .github/workflows/release.yml
- Cargo.lock
permissions:
contents: write
env:
BIN_NAME: chainpilot
HOMEBREW_TAP_REPO: DODOEX/homebrew-chainpilot
AUR_PACKAGE_NAME: chainpilot-bin
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
prepare-release:
name: Prepare Release
runs-on: ubuntu-24.04
outputs:
should_release: ${{ steps.detect.outputs.should_release }}
branch_name: ${{ steps.detect.outputs.branch_name }}
cargo_version: ${{ steps.detect.outputs.cargo_version }}
version: ${{ steps.detect.outputs.version }}
tag: ${{ steps.detect.outputs.tag }}
previous_tag: ${{ steps.detect.outputs.previous_tag }}
prerelease: ${{ steps.detect.outputs.prerelease }}
stable: ${{ steps.detect.outputs.stable }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Validate version and release channel
id: detect
shell: bash
run: |
set -euo pipefail
branch_name="${GITHUB_REF_NAME}"
if [[ -z "$branch_name" ]]; then
echo "Missing branch name from GitHub ref" >&2
exit 1
fi
cargo_version=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n1)
if [[ -z "$cargo_version" ]]; then
echo "Failed to read version from Cargo.toml" >&2
exit 1
fi
version="$cargo_version"
tag="v$version"
is_main=false
if [[ "$branch_name" == "main" ]]; then
is_main=true
fi
prerelease=false
stable=false
if [[ "$version" == *-* ]]; then
prerelease=true
else
stable=true
fi
if [[ "$is_main" == "true" && "$prerelease" == "true" ]]; then
echo "main branch cannot publish prerelease versions: $version — skipping release"
echo "should_release=false" >> "$GITHUB_OUTPUT"
echo "branch_name=$branch_name" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "cargo_version=$cargo_version" >> "$GITHUB_OUTPUT"
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "prerelease=$prerelease" >> "$GITHUB_OUTPUT"
echo "stable=$stable" >> "$GITHUB_OUTPUT"
echo "previous_tag=" >> "$GITHUB_OUTPUT"
exit 0
fi
if [[ "$is_main" != "true" && "$stable" == "true" ]]; then
echo "non-main branch must use prerelease versions with a suffix: $version — skipping release"
echo "should_release=false" >> "$GITHUB_OUTPUT"
echo "branch_name=$branch_name" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "cargo_version=$cargo_version" >> "$GITHUB_OUTPUT"
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "prerelease=$prerelease" >> "$GITHUB_OUTPUT"
echo "stable=$stable" >> "$GITHUB_OUTPUT"
echo "previous_tag=" >> "$GITHUB_OUTPUT"
exit 0
fi
if git rev-parse -q --verify "refs/tags/$tag" >/dev/null; then
echo "Tag $tag already exists"
echo "should_release=false" >> "$GITHUB_OUTPUT"
echo "branch_name=$branch_name" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "cargo_version=$cargo_version" >> "$GITHUB_OUTPUT"
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "prerelease=$prerelease" >> "$GITHUB_OUTPUT"
echo "stable=$stable" >> "$GITHUB_OUTPUT"
previous_tag=$(git tag --sort=-version:refname | head -n1 || true)
echo "previous_tag=$previous_tag" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "should_release=true" >> "$GITHUB_OUTPUT"
echo "branch_name=$branch_name" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "cargo_version=$cargo_version" >> "$GITHUB_OUTPUT"
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "prerelease=$prerelease" >> "$GITHUB_OUTPUT"
echo "stable=$stable" >> "$GITHUB_OUTPUT"
previous_tag=$(git tag --sort=-version:refname | head -n1 || true)
echo "previous_tag=$previous_tag" >> "$GITHUB_OUTPUT"
build:
name: Build ${{ matrix.asset_name }}
needs: prepare-release
if: needs.prepare-release.outputs.should_release == 'true'
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
target: x86_64-unknown-linux-gnu
asset_name: chainpilot-linux-x86_64
archive_ext: tar.gz
binary_name: chainpilot
- os: ubuntu-24.04
target: aarch64-unknown-linux-gnu
asset_name: chainpilot-linux-aarch64
archive_ext: tar.gz
binary_name: chainpilot
- os: macos-14
target: x86_64-apple-darwin
asset_name: chainpilot-macos-x86_64
archive_ext: tar.gz
binary_name: chainpilot
- os: macos-14
target: aarch64-apple-darwin
asset_name: chainpilot-macos-aarch64
archive_ext: tar.gz
binary_name: chainpilot
- os: windows-2022
target: x86_64-pc-windows-msvc
asset_name: chainpilot-windows-x86_64
archive_ext: zip
binary_name: chainpilot.exe
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install cross-compilation tools (Linux aarch64)
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
sudo apt-get update -q
sudo apt-get install -y gcc-aarch64-linux-gnu
- name: Build release binary
env:
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
DODO_API_KEY: ${{ secrets.DODO_API_KEY }}
DODO_PROJECT_ID: ${{ secrets.DODO_PROJECT_ID }}
run: cargo build --release --locked --target ${{ matrix.target }}
- name: Package Unix artifact
if: runner.os != 'Windows'
shell: bash
run: |
mkdir -p dist/${{ matrix.asset_name }}
cp target/${{ matrix.target }}/release/${{ matrix.binary_name }} dist/${{ matrix.asset_name }}/
tar -C dist -czf dist/${{ matrix.asset_name }}.${{ matrix.archive_ext }} ${{ matrix.asset_name }}
- name: Package Windows artifact
if: runner.os == 'Windows'
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path "dist/${{ matrix.asset_name }}" | Out-Null
Copy-Item "target/${{ matrix.target }}/release/${{ matrix.binary_name }}" "dist/${{ matrix.asset_name }}/"
Compress-Archive -Path "dist/${{ matrix.asset_name }}" -DestinationPath "dist/${{ matrix.asset_name }}.${{ matrix.archive_ext }}" -Force
- name: Upload packaged artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.asset_name }}
path: dist/${{ matrix.asset_name }}.${{ matrix.archive_ext }}
release:
name: Publish Release
needs:
- prepare-release
- build
if: needs.prepare-release.outputs.should_release == 'true'
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Create and push tag
env:
TAG: ${{ needs.prepare-release.outputs.tag }}
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag -a "$TAG" -m "Release $TAG"
git push origin "$TAG"
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: Build release notes
id: changelog
uses: mikepenz/release-changelog-builder-action@v5
with:
configuration: .github/release-changelog-config.json
mode: COMMIT
toTag: ${{ needs.prepare-release.outputs.tag }}
fromTag: ${{ needs.prepare-release.outputs.previous_tag }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Publish GitHub release assets
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.prepare-release.outputs.tag }}
name: ${{ needs.prepare-release.outputs.tag }}
body: ${{ steps.changelog.outputs.changelog }}
prerelease: ${{ needs.prepare-release.outputs.prerelease }}
files: dist/*
- name: Checkout Homebrew tap repository
if: needs.prepare-release.outputs.stable == 'true'
uses: actions/checkout@v4
with:
repository: ${{ env.HOMEBREW_TAP_REPO }}
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
path: homebrew-tap
- name: Update Homebrew formula
if: needs.prepare-release.outputs.stable == 'true'
env:
VERSION: ${{ needs.prepare-release.outputs.cargo_version }}
TAG: ${{ needs.prepare-release.outputs.tag }}
shell: bash
run: |
set -euo pipefail
linux_x86_url="https://github.com/${GITHUB_REPOSITORY}/releases/download/${TAG}/chainpilot-linux-x86_64.tar.gz"
linux_arm_url="https://github.com/${GITHUB_REPOSITORY}/releases/download/${TAG}/chainpilot-linux-aarch64.tar.gz"
macos_x86_url="https://github.com/${GITHUB_REPOSITORY}/releases/download/${TAG}/chainpilot-macos-x86_64.tar.gz"
macos_arm_url="https://github.com/${GITHUB_REPOSITORY}/releases/download/${TAG}/chainpilot-macos-aarch64.tar.gz"
linux_x86_sha=$(sha256sum dist/chainpilot-linux-x86_64.tar.gz | awk '{print $1}')
linux_arm_sha=$(sha256sum dist/chainpilot-linux-aarch64.tar.gz | awk '{print $1}')
macos_x86_sha=$(sha256sum dist/chainpilot-macos-x86_64.tar.gz | awk '{print $1}')
macos_arm_sha=$(sha256sum dist/chainpilot-macos-aarch64.tar.gz | awk '{print $1}')
mkdir -p homebrew-tap/Formula
cat > homebrew-tap/Formula/chainpilot.rb <<EOF
class Chainpilot < Formula
desc "CLI tool for on-chain DeFi operations on EVM-compatible networks"
homepage "https://github.com/${GITHUB_REPOSITORY}"
version "${VERSION}"
license "MIT"
on_macos do
on_arm do
url "${macos_arm_url}"
sha256 "${macos_arm_sha}"
end
on_intel do
url "${macos_x86_url}"
sha256 "${macos_x86_sha}"
end
end
on_linux do
on_arm do
url "${linux_arm_url}"
sha256 "${linux_arm_sha}"
end
on_intel do
url "${linux_x86_url}"
sha256 "${linux_x86_sha}"
end
end
def install
bin.install "chainpilot"
end
test do
assert_match version.to_s, shell_output("#{bin}/chainpilot --version")
end
end
EOF
- name: Commit and push Homebrew formula update
if: needs.prepare-release.outputs.stable == 'true'
shell: bash
run: |
set -euo pipefail
cd homebrew-tap
if git diff --quiet; then
echo "No Homebrew formula changes to commit."
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add Formula/chainpilot.rb
git commit -m "chainpilot ${{ needs.prepare-release.outputs.version }}"
git push origin HEAD
- name: Check AUR SSH key
if: needs.prepare-release.outputs.stable == 'true'
id: aur-key
shell: bash
env:
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
run: |
if [[ -n "${AUR_SSH_PRIVATE_KEY}" ]]; then
echo "available=true" >> "$GITHUB_OUTPUT"
else
echo "available=false" >> "$GITHUB_OUTPUT"
echo "AUR_SSH_PRIVATE_KEY is not configured. Skipping AUR update."
fi
- name: Install SSH key for AUR
if: needs.prepare-release.outputs.stable == 'true' && steps.aur-key.outputs.available == 'true'
shell: bash
env:
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
run: |
set -euo pipefail
mkdir -p ~/.ssh
chmod 700 ~/.ssh
printf '%s\n' "$AUR_SSH_PRIVATE_KEY" > ~/.ssh/aur
chmod 600 ~/.ssh/aur
ssh-keyscan aur.archlinux.org >> ~/.ssh/known_hosts
- name: Clone AUR repository
if: needs.prepare-release.outputs.stable == 'true' && steps.aur-key.outputs.available == 'true'
shell: bash
run: |
set -euo pipefail
GIT_SSH_COMMAND='ssh -i ~/.ssh/aur' \
git clone "ssh://aur@aur.archlinux.org/${AUR_PACKAGE_NAME}.git" aur-repo
- name: Update PKGBUILD and .SRCINFO
if: needs.prepare-release.outputs.stable == 'true' && steps.aur-key.outputs.available == 'true'
shell: bash
env:
TAG: ${{ needs.prepare-release.outputs.tag }}
run: |
set -euo pipefail
version="${TAG#v}"
url="https://github.com/${GITHUB_REPOSITORY}/releases/download/${TAG}/chainpilot-linux-x86_64.tar.gz"
sha256="$(curl -fsSL "$url" | sha256sum | awk '{print $1}')"
{
printf '%s\n' '# Maintainer: DODOEX <maintainers@dodoex.io>'
printf '\n'
printf '%s\n' 'pkgname=chainpilot-bin'
printf '%s\n' "pkgver=${version}"
printf '%s\n' 'pkgrel=1'
printf '%s\n' 'pkgdesc="CLI tool for on-chain DeFi operations on EVM-compatible networks"'
printf '%s\n' "url=\"https://github.com/${GITHUB_REPOSITORY}\""
printf '%s\n' "source=(\"\$pkgname-\$pkgver.tar.gz::https://github.com/${GITHUB_REPOSITORY}/releases/download/v\$pkgver/chainpilot-linux-x86_64.tar.gz\")"
printf '%s\n' 'arch=('\''x86_64'\'')'
printf '%s\n' 'license=('\''MIT'\'')'
printf '%s\n' 'provides=('\''chainpilot'\'')'
printf '%s\n' 'conflicts=('\''chainpilot'\'')'
printf '%s\n' "sha256sums=('${sha256}')"
printf '\n'
printf '%s\n' 'package() {'
printf '%s\n' ' install -Dm755 "$srcdir/chainpilot-linux-x86_64/chainpilot" "$pkgdir/usr/bin/chainpilot"'
printf '%s\n' '}'
} > aur-repo/PKGBUILD
{
printf '%s\n' 'pkgbase = chainpilot-bin'
printf '%s\n' ' pkgdesc = CLI tool for on-chain DeFi operations on EVM-compatible networks'
printf '%s\n' " pkgver = ${version}"
printf '%s\n' ' pkgrel = 1'
printf '%s\n' " url = https://github.com/${GITHUB_REPOSITORY}"
printf '%s\n' ' arch = x86_64'
printf '%s\n' ' license = MIT'
printf '%s\n' ' conflicts = chainpilot'
printf '%s\n' ' provides = chainpilot'
printf '%s\n' " source = chainpilot-bin-${version}.tar.gz::https://github.com/${GITHUB_REPOSITORY}/releases/download/v${version}/chainpilot-linux-x86_64.tar.gz"
printf '%s\n' " sha256sums = ${sha256}"
printf '\n'
printf '%s\n' 'pkgname = chainpilot-bin'
} > aur-repo/.SRCINFO
- name: Commit and push AUR update
if: needs.prepare-release.outputs.stable == 'true' && steps.aur-key.outputs.available == 'true'
shell: bash
run: |
set -euo pipefail
cd aur-repo
if git diff --quiet; then
echo "No AUR changes to commit."
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add PKGBUILD .SRCINFO
git commit -m "Update to ${AUR_PACKAGE_NAME} ${GITHUB_REF_NAME#v}"
GIT_SSH_COMMAND='ssh -i ~/.ssh/aur' git push origin master