diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..4e93a4b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,347 @@ +name: Release +run-name: Release ${{ github.ref_name }} +on: + push: + branches: + - 'main' + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +env: + #rust-musl-cross:x86_64-musl + RUST_MUSL_CROSS_IMAGE: messense/rust-musl-cross@sha256:68b86bc7cb2867259e6b233415a665ff4469c28b57763e78c3bfea1c68091561 + +jobs: + + # + # + # + tag: + runs-on: ubuntu-24.04 + permissions: + contents: write + outputs: + TAG: ${{ steps.versions.outputs.TAG }} + PKG_VER: ${{ steps.versions.outputs.PKG_VER }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-tags: 'true' + fetch-depth: 0 + + - name: Versions + id: versions + run: | + export CURRENT_TAG=$(git describe --tags --abbrev=0 --exclude "llvm-*") + export PKG_VER=v$(cat Cargo.toml | grep -A 5 package] | grep version | cut -d '=' -f 2 | tr -d '"' | tr -d " ") + echo "Current tag $CURRENT_TAG" + echo "Package version $PKG_VER" + # + echo "PKG_VER=$PKG_VER" >> $GITHUB_OUTPUT + if [ $CURRENT_TAG == $PKG_VER ]; + then + echo "Tag is up to date. Nothing to do."; + export TAG=old; + else + echo "Tag was updated."; + export TAG=new; + fi + echo "TAG=$TAG" >> $GITHUB_OUTPUT + + # + # + # + build-linux-all: + if: ${{ needs.tag.outputs.TAG == 'new' }} + runs-on: parity-large + needs: [tag] + steps: + - uses: actions/checkout@v4 + + - name: install linux deps + run: | + sudo apt-get update && sudo apt-get install -y cmake ninja-build \ + curl git libssl-dev pkg-config clang lld musl + + - name: Install Rust stable toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + components: rust-src + target: wasm32-unknown-emscripten + + - name: versions + run: | + rustup show + cargo --version + cmake --version + echo "bash:" && bash --version + echo "ninja:" && ninja --version + echo "clang:" && clang --version + + - name: build revive-llvm + run: make install-llvm-builder + + # musl LLVM + + - name: llvm-musl-cache restore + id: llvm-musl-cache + uses: actions/cache/restore@v4 + with: + path: target-llvm/musl/target-final + key: llvm-linux-musl-${{ hashFiles('crates/solidity/**') }} + + - name: Build musl LLVM + if: steps.llvm-musl-cache.outputs.cache-hit != 'true' + run: | + revive-llvm --target-env musl clone + revive-llvm --target-env musl build --llvm-projects lld --llvm-projects clang + + - name: llvm-musl-cache save + if: steps.llvm-musl-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: target-llvm/musl/target-final + key: llvm-linux-musl-${{ hashFiles('crates/solidity/**') }} + + # emscripten LLVM + + - name: llvm-emscripten-cache restore + id: llvm-emscripten-cache + uses: actions/cache/restore@v4 + with: + path: | + target-llvm/emscripten/target-final + emsdk + key: llvm-linux-emscripten-${{ hashFiles('crates/solidity/**') }} + + - name: Build emscripten LLVM + if: steps.llvm-emscripten-cache.outputs.cache-hit != 'true' + run: | + revive-llvm --target-env emscripten clone + source emsdk/emsdk_env.sh + revive-llvm --target-env emscripten build --llvm-projects lld + + - name: llvm-emscripten-cache save + if: steps.llvm-emscripten-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: | + target-llvm/emscripten/target-final + emsdk + key: llvm-linux-emscripten-${{ hashFiles('crates/solidity/**') }} + + # Build revive + + - name: build musl + run: | + mkdir resolc-out + docker run -v $PWD:/opt/revive $RUST_MUSL_CROSS_IMAGE /bin/bash -c " + cd /opt/revive + apt update && apt upgrade -y && apt install -y pkg-config + export LLVM_SYS_181_PREFIX=/opt/revive/target-llvm/musl/target-final + make install-bin + cp /root/.cargo/bin/resolc /opt/revive/resolc-out/resolc + " + + - name: check musl + run: | + mkdir solc + curl -sSLo solc/solc https://github.com/ethereum/solidity/releases/download/v0.8.28/solc-static-linux + chmod +x solc/solc + PATH=$PWD/solc:$PATH + result=$(./resolc-out/resolc --bin crates/integration/contracts/flipper.sol) + echo $result + if [[ $result == *'0x50564d'* ]]; then exit 0; else exit 1; fi + + - name: Set Up Node.js + uses: actions/setup-node@v3 + with: + node-version: "20" + + - name: build wasm + run: | + export LLVM_SYS_181_PREFIX=$PWD/target-llvm/musl/target-final + export REVIVE_LLVM_TARGET_PREFIX=$PWD/target-llvm/emscripten/target-final + source emsdk/emsdk_env.sh + rustup target add wasm32-unknown-emscripten + make install-wasm + + - name: check wasm + run: | + curl -sSLo solc/soljson.js https://github.com/ethereum/solidity/releases/download/v0.8.28/soljson.js + node -e " + const soljson = require('solc/soljson'); + const createRevive = require('./target/wasm32-unknown-emscripten/release/resolc.js'); + + const compiler = createRevive(); + compiler.soljson = soljson; + + const standardJsonInput = + { + language: 'Solidity', + sources: { + 'MyContract.sol': { + content: 'pragma solidity ^0.8.0; contract MyContract { function greet() public pure returns (string memory) { return \'Hello\'; } }', + }, + }, + settings: { optimizer: { enabled: false } } + }; + + compiler.writeToStdin(JSON.stringify(standardJsonInput)); + compiler.callMain(['--standard-json']); + + // Collect output + const stdout = compiler.readFromStdout(); + const stderr = compiler.readFromStderr(); + + if (stderr) { console.error(stderr); process.exit(1); } + + let out = JSON.parse(stdout); + let bytecode = out.contracts['MyContract.sol']['MyContract'].evm.bytecode.object + console.log(bytecode); + + if(!bytecode.startsWith('50564d')) { process.exit(1); } + " + + - uses: actions/upload-artifact@v4 + with: + name: revive-wasm + path: | + ./target/wasm32-unknown-emscripten/release/resolc.js + ./target/wasm32-unknown-emscripten/release/resolc.wasm + ./target/wasm32-unknown-emscripten/release/resolc_web.js + retention-days: 1 + + - uses: actions/upload-artifact@v4 + with: + name: revive-linux + path: | + ./resolc-out/resolc + retention-days: 1 + + # + # + # + create-release: + needs: [tag, build-linux-all] + runs-on: ubuntu-24.04 + permissions: + contents: write + outputs: + upload_url: ${{ steps.create_release.outputs.result }} + steps: + - uses: actions/checkout@v4 + + - name: Create/update tag + id: tag + uses: actions/github-script@v7 + with: + result-encoding: string + script: | + await github.rest.git.createRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: 'refs/tags/${{ needs.tag.outputs.PKG_VER }}', + sha: context.sha + }) + + - name: get relese notes + id: get-notes + run: | + { + echo 'releaseNotes<> "$GITHUB_OUTPUT" + + + - name: Create release + id: create_release + env: + releaseNotes: ${{ steps.get-notes.outputs.releaseNotes }} + version: ${{ needs.tag.outputs.PKG_VER }} + uses: actions/github-script@v7 + with: + result-encoding: string + script: | + let response = await github.rest.repos.createRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + tag_name: process.env.version, + name: process.env.version, + body: process.env.releaseNotes, + draft: true, + prerelease: true + }); + console.log(response); + return response.data.upload_url; + + - name: Log + run: | + echo "tag result: ${{ needs.tag.outputs.TAG }}" + echo "pkg version: ${{ needs.tag.outputs.PKG_VER }}" + + # + # + # + upload-assets: + runs-on: ubuntu-24.04 + needs: [create-release] + steps: + + - name: Download Artifact + uses: actions/download-artifact@v4 + with: + name: revive-wasm + path: resolc/ + + - name: Download Artifact + uses: actions/download-artifact@v4 + with: + name: revive-linux + path: resolc/ + + - name: upload resolc + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create-release.outputs.upload_url }} + asset_path: ./resolc/resolc + asset_name: resolc-static-linux + asset_content_type: application/octet-stream + + - name: upload resolc.js + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create-release.outputs.upload_url }} + asset_path: ./resolc/resolc.js + asset_name: resolc.js + asset_content_type: application/octet-stream + + - name: upload resolc.wasm + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create-release.outputs.upload_url }} + asset_path: ./resolc/resolc.wasm + asset_name: resolc.wasm + asset_content_type: application/octet-stream + + - name: upload resolc_web.js + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create-release.outputs.upload_url }} + asset_path: ./resolc/resolc_web.js + asset_name: resolc_web.js + asset_content_type: application/octet-stream \ No newline at end of file diff --git a/RELEASE.md b/RELEASE.md index fa3e543..b3a2868 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -4,8 +4,7 @@ Prior to the first stable release we neither have formal release processes nor d To create a new pre-release: -1. Merge a release PR which updates the `-dev.X` versions in the workspace `Cargo.toml` and updates the `CHANGELOG.md` accordingly -2. Push a release tag to `main` -3. Create a __pre-release__ from the tag and manually upload the `resolc` binary from docker image -4. Manually upload `resolc.js`, `resolc-web.js` and `resolc.wasm` from the `build-revive-wasm` action artifacts. -5. Update the [contract-docs](https://github.com/paritytech/contract-docs/) accordingly +1. Merge a release PR which updates the `-dev.X` versions in the workspace `Cargo.toml` and updates the `CHANGELOG.md` accordingly. The release workflow will attempt to build and publish a new release whenever the latest git tag does not match the cargo package version. +2. Wait for the `Release` workflow to finish. If the workflow fails after the `build-linux-all` step, check if a tag has been created and delete it before restarting or pushing updates. Note: It's more convenient to debug the release workflow in a fork (the fork has to be under the `paritytech` org to access `parity-large` runners). +3. Check draft release on [Releases page](https://github.com/paritytech/revive/releases) and publish (should contain `resolc.js`, `resolc.wasm`, `resolc-web.js`, and `resolc-static-linux` release assets) +4. Update the [contract-docs](https://github.com/paritytech/contract-docs/) accordingly \ No newline at end of file