From f571591c5548214189343b6d847af5351c7fd71f Mon Sep 17 00:00:00 2001 From: Mahmoud Mazouz Date: Thu, 14 Mar 2024 13:21:50 +0100 Subject: [PATCH] feat: Improve Release workflow --- .github/workflows/Dockerfile | 42 --- .github/workflows/release.yml | 516 ++++++++++++---------------------- 2 files changed, 180 insertions(+), 378 deletions(-) delete mode 100644 .github/workflows/Dockerfile diff --git a/.github/workflows/Dockerfile b/.github/workflows/Dockerfile deleted file mode 100644 index 4855a16..0000000 --- a/.github/workflows/Dockerfile +++ /dev/null @@ -1,42 +0,0 @@ -# -# Copyright (c) 2022 ZettaScale Technology -# -# This program and the accompanying materials are made available under the -# terms of the Eclipse Public License 2.0 which is available at -# http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -# which is available at https://www.apache.org/licenses/LICENSE-2.0. -# -# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -# -# Contributors: -# ZettaScale Zenoh Team, -# - -### -### Dockerfile creating the eclipse/zenoh-bridge-ros2dds image from cross-compiled binaries. -### It assumes that zenoh-bridge-ros2dds is installed in docker/$TARGETPLATFORM/ -### where $TARGETPLATFORM is set by buildx to a Docker supported platform such as linux/amd64 or linux/arm64 -### (see https://docs.docker.com/buildx/working-with-buildx/#build-multi-platform-images) -### - - -FROM alpine:latest - -ARG TARGETPLATFORM - -RUN apk add --no-cache libgcc libstdc++ - -COPY docker/$TARGETPLATFORM/zenoh-bridge-ros2dds / - -RUN echo '#!/bin/ash' > /entrypoint.sh -RUN echo 'echo " * Starting: /zenoh-bridge-ros2dds $*"' >> /entrypoint.sh -RUN echo 'exec /zenoh-bridge-ros2dds $*' >> /entrypoint.sh -RUN chmod +x /entrypoint.sh - -EXPOSE 7446/udp -EXPOSE 7447/tcp -EXPOSE 8000/tcp - -ENV RUST_LOG info - -ENTRYPOINT ["/entrypoint.sh"] diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3613413..34d332c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,343 +14,187 @@ name: Release on: - release: - types: [published] schedule: - - cron: "0 1 * * 1-5" + - cron: "0 0 * * 1-5" workflow_dispatch: + inputs: + live-run: + type: boolean + description: If false (or undefined) the workflow runs in dry-run mode (i.e. with no side-effects) + required: false + version: + type: string + description: Release number. If undefined, the workflow auto-generates a version using git-describe + required: false + zenoh-version: + type: string + description: Release number of Zenoh. Required in live-run mode and ignored in dry-run mode + required: false jobs: - checks: - name: Code checks - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Install Rust toolchain - run: | - rustup show - rustup component add rustfmt clippy - - name: Code format check - run: cargo fmt --check - - name: Clippy check - run: cargo clippy -- -D warnings - - name: Environment setup - id: env - shell: bash - run: | - # log some info - gcc --version || true - rustup -V - rustup toolchain list - rustup default - cargo -V - rustc -V - - echo "GITHUB_REF=${GITHUB_REF}" - echo "GITHUB_SHA=${GITHUB_SHA:0:8}" - GIT_BRANCH=`[[ $GITHUB_REF =~ ^refs/heads/.* ]] && echo ${GITHUB_REF/refs\/heads\//} || true` - echo "GIT_BRANCH=${GIT_BRANCH}" >> $GITHUB_OUTPUT - GIT_TAG=`[[ $GITHUB_REF =~ ^refs/tags/.* ]] && echo ${GITHUB_REF/refs\/tags\//} || true` - echo "GIT_TAG=${GIT_TAG}" >> $GITHUB_OUTPUT - - sudo apt-get update - sudo apt-get install -y jq - - ZENOH_VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "zenoh-plugin-ros2dds") | .version') - echo "ZENOH_VERSION=${ZENOH_VERSION}" >> $GITHUB_OUTPUT - if [ -n "${GIT_TAG}" ]; then - IS_RELEASE="true" - echo "IS_RELEASE=${IS_RELEASE}" >> $GITHUB_OUTPUT - PKG_VERSION=${ZENOH_VERSION} - elif [ -n "${GIT_BRANCH}" ]; then - PKG_VERSION=${GIT_BRANCH}-${GITHUB_SHA:0:8} - else - PKG_VERSION=${ZENOH_VERSION}-${GITHUB_SHA:0:8} - fi - echo "PKG_VERSION=${PKG_VERSION}" >> $GITHUB_OUTPUT - cat ${GITHUB_OUTPUT} - outputs: - GIT_BRANCH: ${{ steps.env.outputs.GIT_BRANCH }} - GIT_TAG: ${{ steps.env.outputs.GIT_TAG }} - IS_RELEASE: ${{ steps.env.outputs.IS_RELEASE }} - ZENOH_VERSION: ${{ steps.env.outputs.ZENOH_VERSION }} - PKG_VERSION: ${{ steps.env.outputs.PKG_VERSION }} - - builds: - name: Build for ${{ matrix.job.target }} on ${{ matrix.job.os }} - needs: checks - runs-on: ${{ matrix.job.os }} - strategy: - fail-fast: false - matrix: - job: - - { - target: x86_64-unknown-linux-gnu, - arch: amd64, - os: ubuntu-22.04, - build-cmd: "cargo", - } - - { - target: x86_64-apple-darwin, - arch: darwin, - os: macos-12, - build-cmd: "cargo", - } - - { - target: aarch64-apple-darwin, - arch: darwin, - os: macos-12, - build-cmd: "cargo", - } - - { - target: x86_64-unknown-linux-musl, - arch: amd64, - os: ubuntu-22.04, - build-cmd: "cross", - } - - { - target: arm-unknown-linux-gnueabi, - arch: armel, - os: ubuntu-22.04, - build-cmd: "cross", - } - - { - target: arm-unknown-linux-gnueabihf, - arch: armhf, - os: ubuntu-22.04, - build-cmd: "cross", - } - - { - target: armv7-unknown-linux-gnueabihf, - arch: armhf, - os: ubuntu-22.04, - build-cmd: "cross", - } - - { - target: aarch64-unknown-linux-gnu, - arch: arm64, - os: ubuntu-22.04, - build-cmd: "cross", - } - - { - target: aarch64-unknown-linux-musl, - arch: arm64, - os: ubuntu-22.04, - build-cmd: "cross", - } - - { - target: x86_64-pc-windows-msvc, - arch: win64, - os: windows-2022, - build-cmd: "cargo", - } - ## - ## NOTE: cannon build for Windows GNU as not supported by cyclors - ## - # - { - # target: x86_64-pc-windows-gnu, - # arch: win64, - # os: windows-2022, - # build-cmd: "cargo", - # } - steps: - - name: Checkout source code - uses: actions/checkout@v4 - with: - fetch-depth: 500 # NOTE: get long history for git-version crate to correctly compute a version - - name: Fetch Git tags # NOTE: workaround for https://github.com/actions/checkout/issues/290 - shell: bash - run: git fetch --tags --force - - name: Install prerequisites - shell: bash - run: | - case ${{ matrix.job.target }} in - *-linux-gnu*) cargo install cargo-deb;; - esac - - case ${{ matrix.job.target }} in - arm-unknown-linux-gnueabi) - sudo apt-get -y update - sudo apt-get -y install gcc-arm-linux-gnueabi - ;; - arm*-unknown-linux-gnueabihf) - sudo apt-get -y update - sudo apt-get -y install gcc-arm-linux-gnueabihf - ;; - aarch64-unknown-linux-gnu) - sudo apt-get -y update - sudo apt-get -y install gcc-aarch64-linux-gnu - ;; - esac - - cargo install cross --version 0.2.5 - - - name: Install Rust toolchain - run: | - rustup show - rustup target add ${{ matrix.job.target }} - - - name: zenoh-plugin-ros2dds > Build - run: ${{ matrix.job.build-cmd }} build --release --target=${{ matrix.job.target }} -p zenoh-plugin-ros2dds - - - name: zenoh-bridge-ros2dds > Build - run: ${{ matrix.job.build-cmd }} build --release --target=${{ matrix.job.target }} -p zenoh-bridge-ros2dds - - - name: zenoh-plugin-ros2dds > Debian package - if: contains(matrix.job.target, '-linux-gnu') - run: cargo deb --no-build --target=${{ matrix.job.target }} -p zenoh-plugin-ros2dds - - - name: zenoh-bridge-ros2dds > Debian package - if: contains(matrix.job.target, '-linux-gnu') - run: cargo deb --no-build --target=${{ matrix.job.target }} -p zenoh-bridge-ros2dds - - - name: Packaging - id: package - shell: bash - run: | - TARGET=${{ matrix.job.target }} - LIB_PKG_NAME="${GITHUB_WORKSPACE}/zenoh-plugin-ros2dds-${{ needs.checks.outputs.PKG_VERSION }}-${TARGET}.zip" - BIN_PKG_NAME="${GITHUB_WORKSPACE}/zenoh-bridge-ros2dds-${{ needs.checks.outputs.PKG_VERSION }}-${TARGET}.zip" - DEBS_PKG_NAME="${GITHUB_WORKSPACE}/zenoh-plugin-ros2dds-${{ needs.checks.outputs.PKG_VERSION }}-${TARGET}-deb-pkgs.zip" - - case ${TARGET} in - *linux*) - cd "target/${TARGET}/release/" - echo "Packaging ${LIB_PKG_NAME}:" - zip ${LIB_PKG_NAME} libzenoh_plugin*.so - echo "Packaging ${BIN_PKG_NAME}:" - zip ${BIN_PKG_NAME} zenoh-bridge-ros2dds - cd - - echo "LIB_PKG_NAME=${LIB_PKG_NAME}" >> $GITHUB_OUTPUT - echo "BIN_PKG_NAME=${BIN_PKG_NAME}" >> $GITHUB_OUTPUT - - # check if debian packages has been created and packages them in a single tgz - if [[ -d target/${TARGET}/debian ]]; then - cd target/${TARGET}/debian - echo "Packaging ${DEBS_PKG_NAME}:" - zip ${DEBS_PKG_NAME} *.deb - cd - - echo "DEBS_PKG_NAME=${DEBS_PKG_NAME}" >> $GITHUB_OUTPUT - fi - ;; - *apple*) - cd "target/${TARGET}/release/" - echo "Packaging ${LIB_PKG_NAME}:" - zip ${LIB_PKG_NAME} libzenoh_plugin*.dylib - echo "Packaging ${BIN_PKG_NAME}:" - zip ${BIN_PKG_NAME} zenoh-bridge-ros2dds - cd - - echo "LIB_PKG_NAME=${LIB_PKG_NAME}" >> $GITHUB_OUTPUT - echo "BIN_PKG_NAME=${BIN_PKG_NAME}" >> $GITHUB_OUTPUT - ;; - *windows*) - cd "target/${TARGET}/release/" - echo "Packaging ${LIB_PKG_NAME}:" - 7z -y a "${LIB_PKG_NAME}" zenoh_plugin*.dll - echo "Packaging ${BIN_PKG_NAME}:" - 7z -y a "${BIN_PKG_NAME}" zenoh-bridge-ros2dds.exe - cd - - echo "LIB_PKG_NAME=${LIB_PKG_NAME}" >> $GITHUB_OUTPUT - echo "BIN_PKG_NAME=${BIN_PKG_NAME}" >> $GITHUB_OUTPUT - ;; - esac - - - name: "Upload packages" - uses: actions/upload-artifact@v3 - with: - name: ${{ matrix.job.target }} - path: | - ${{ steps.package.outputs.LIB_PKG_NAME }} - ${{ steps.package.outputs.BIN_PKG_NAME }} - ${{ steps.package.outputs.DEBS_PKG_NAME }} - - docker-build: - name: Docker build and push - needs: [checks, builds] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 500 # NOTE: get long history for git-version crate to correctly compute a version - - name: Fetch Git tags # NOTE: workaround for https://github.com/actions/checkout/issues/290 - shell: bash - run: git fetch --tags --force - - name: Download packages from previous job - uses: actions/download-artifact@v3 - with: - path: PACKAGES - - name: Unzip PACKAGES - run: | - ls PACKAGES - mkdir -p docker/linux/amd - unzip PACKAGES/x86_64-unknown-linux-musl/zenoh-bridge-ros2dds-${{ needs.checks.outputs.PKG_VERSION }}-x86_64-unknown-linux-musl.zip -d docker/linux/amd64/ - mkdir -p docker/linux/arm64 - unzip PACKAGES/aarch64-unknown-linux-musl/zenoh-bridge-ros2dds-${{ needs.checks.outputs.PKG_VERSION }}-aarch64-unknown-linux-musl.zip -d docker/linux/arm64/ - tree docker - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Docker meta - set tags and labels - id: meta - uses: docker/metadata-action@v5 - with: - images: eclipse/zenoh-bridge-ros2dds - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_COM_USERNAME }} - password: ${{ secrets.DOCKER_COM_PASSWORD }} - - name: Build and push - uses: docker/build-push-action@v5 - with: - context: . - platforms: linux/amd64,linux/arm64 - file: .github/workflows/Dockerfile - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - - publication: - name: Release publication - if: needs.checks.outputs.IS_RELEASE == 'true' - needs: [checks, builds] - runs-on: ubuntu-latest - steps: - - name: Download result of previous builds - uses: actions/download-artifact@v3 - with: - path: ARTIFACTS - - name: Publish as github release - uses: softprops/action-gh-release@v1 - with: - files: ARTIFACTS/*/*.* - - name: Publish to download.eclipse.org/zenoh - env: - SSH_TARGET: genie.zenoh@projects-storage.eclipse.org - ECLIPSE_BASE_DIR: /home/data/httpd/download.eclipse.org/zenoh/zenoh-plugin-ros2dds - shell: bash - run: | - echo "--- setup ssh-agent" - eval "$(ssh-agent -s)" - echo 'echo "${{ secrets.SSH_PASSPHRASE }}"' > ~/.ssh_askpass && chmod +x ~/.ssh_askpass - echo "${{ secrets.SSH_PRIVATE_KEY }}" | tr -d '\r' | DISPLAY=NONE SSH_ASKPASS=~/.ssh_askpass ssh-add - > /dev/null 2>&1 - rm -f ~/.ssh_askpass - echo "--- test ssh:" - ssh -o "StrictHostKeyChecking=no" ${SSH_TARGET} ls -al - echo "---- list artifacts to upload:" - ls -R ARTIFACTS || true - DOWNLOAD_DIR=${ECLIPSE_BASE_DIR}/${{ needs.checks.outputs.ZENOH_VERSION }} - echo "---- copy artifacts into ${DOWNLOAD_DIR}" - ssh -o "StrictHostKeyChecking=no" ${SSH_TARGET} mkdir -p ${DOWNLOAD_DIR} - cd ARTIFACTS - sha256sum */* > sha256sums.txt - scp -o "StrictHostKeyChecking=no" -r * ${SSH_TARGET}:${DOWNLOAD_DIR}/ - echo "---- cleanup identity" - ssh-add -D - - uses: actions/checkout@v4 - - name: Install Rust toolchain - run: rustup show - - name: Publish to crates.io - shell: bash - run: | - cargo login ${{ secrets.CRATES_IO_TOKEN }} - (cd zenoh-plugin-ros2dds && cargo publish) + tag: + name: Bump and tag crates + uses: eclipse-zenoh/ci/.github/workflows/tag-crates.yml@main + with: + repo: ${{ github.repository }} + live-run: ${{ inputs.live-run }} + version: ${{ inputs.version }} + inter-deps-pattern: ${{ inputs.live-run && 'zenoh.*' || '^$' }} + inter-deps-version: ${{ inputs.live-run && inputs.zenoh-version || '' }} + secrets: inherit + + build-debian: + name: Build Debian packages + needs: tag + uses: eclipse-zenoh/ci/.github/workflows/build-crates-debian.yml@main + with: + repo: ${{ github.repository }} + version: ${{ needs.tag.outputs.version }} + branch: ${{ needs.tag.outputs.branch }} + secrets: inherit + + build-standalone: + name: Build executables and libraries + needs: tag + uses: eclipse-zenoh/ci/.github/workflows/build-crates-standalone.yml@main + with: + repo: ${{ github.repository }} + version: ${{ needs.tag.outputs.version }} + branch: ${{ needs.tag.outputs.branch }} + # NOTE: x86_64-pc-windows-gnu is not supported by cyclors + exclude-builds: '[{ build: { target: "x86_64-pc-windows-gnu", os: "windows-2019" } }]' + artifact-patterns: | + ^zenoh-bridge-ros2dds(\.exe)?$ + ^libzenoh_plugin_ros2dds\.(dylib|so)$ + ^zenoh_plugin_ros2dds\.dll$ + secrets: inherit + + cargo-live-run: + if: ${{ inputs.live-run }} + name: Publish Cargo crates (live-run) + needs: tag + uses: eclipse-zenoh/ci/.github/workflows/release-crates-cargo.yml@main + with: + repos: ${{ github.repository }} + live-run: true + branch: ${{ needs.tag.outputs.branch }} + inter-deps-pattern: ^$ + secrets: inherit + + # In dry-run mode, we need to publish eclipse-zenoh/zenoh before this repository, + # in which case the version of zenoh dependecies are left as is and thus point to + # the main branch of eclipse-zenoh/zenoh + cargo-dry-run: + if: ${{ !inputs.live-run }} + name: Publish Cargo crates (dry-run) + needs: tag + uses: eclipse-zenoh/ci/.github/workflows/release-crates-cargo.yml@main + with: + repos: | + eclipse-zenoh/zenoh + ${{ github.repository }} + live-run: false + branch: ${{ needs.tag.outputs.branch }} + inter-deps-pattern: zenoh.* + secrets: inherit + + debian: + name: Publish Debian packages + needs: [tag, build-debian] + uses: eclipse-zenoh/ci/.github/workflows/release-crates-debian.yml@main + with: + no-build: true + live-run: ${{ inputs.live-run }} + version: ${{ needs.tag.outputs.version }} + repo: ${{ github.repository }} + branch: ${{ needs.tag.outputs.branch }} + secrets: inherit + + homebrew: + name: Publish Homebrew formulae + needs: [tag, build-standalone] + uses: eclipse-zenoh/ci/.github/workflows/release-crates-homebrew.yml@main + with: + no-build: true + repo: ${{ github.repository }} + live-run: ${{ inputs.live-run }} + version: ${{ needs.tag.outputs.version }} + branch: ${{ needs.tag.outputs.branch }} + artifact-patterns: | + ^zenoh-bridge-ros2dds$ + ^libzenoh_plugin_ros2dds\.dylib$ + formulae: | + zenoh-bridge-ros2dds + zenoh-plugin-ros2dds + secrets: inherit + + eclipse: + name: Publish artifacts to Eclipse downloads + needs: [tag, build-standalone] + uses: eclipse-zenoh/ci/.github/workflows/release-crates-eclipse.yml@main + with: + no-build: true + live-run: ${{ inputs.live-run }} + version: ${{ needs.tag.outputs.version }} + repo: ${{ github.repository }} + branch: ${{ needs.tag.outputs.branch }} + artifact-patterns: | + ^zenoh-bridge-ros2dds(\.exe)?$ + ^libzenoh_plugin_ros2dds\.(dylib|so)$ + ^zenoh_plugin_ros2dds\.dll$ + name: zenoh-plugin-ros2dds + secrets: inherit + + github: + name: Publish artifacts to GitHub Releases + needs: [tag, build-standalone] + uses: eclipse-zenoh/ci/.github/workflows/release-crates-github.yml@main + with: + no-build: true + live-run: ${{ inputs.live-run }} + version: ${{ needs.tag.outputs.version }} + repo: ${{ github.repository }} + branch: ${{ needs.tag.outputs.branch }} + artifact-patterns: | + ^zenoh-bridge-ros2dds(\.exe)?$ + ^libzenoh_plugin_ros2dds\.(dylib|so)$ + ^zenoh_plugin_ros2dds\.dll$ + secrets: inherit + + dockerhub: + name: Publish container image to DockerHub + needs: [tag, build-standalone] + uses: eclipse-zenoh/ci/.github/workflows/release-crates-dockerhub.yml@main + with: + no-build: true + live-run: ${{ inputs.live-run }} + version: ${{ needs.tag.outputs.version }} + repo: ${{ github.repository }} + tags: "eclipse/zenoh-plugin-ros2dds:${{ needs.tag.outputs.version }}" + binary: zenoh-bridge-ros2dds + files: | + zenoh-bridge-ros2dds + libzenoh_plugin_ros2dds.so + platforms: | + linux/arm64 + linux/amd64 + secrets: inherit + + ghcr: + name: Publish container image to GitHub Container Registry + needs: [tag, build-standalone] + uses: eclipse-zenoh/ci/.github/workflows/release-crates-ghcr.yml@main + with: + no-build: true + live-run: ${{ inputs.live-run }} + version: ${{ needs.tag.outputs.version }} + repo: ${{ github.repository }} + tags: "${{ github.repository }}:${{ needs.tag.outputs.version }}" + binary: zenoh-bridge-ros2dds + files: | + zenoh-bridge-ros2dds + libzenoh_plugin_ros2dds.so + platforms: | + linux/arm64 + linux/amd64 + secrets: inherit