From b7a2ebf31130d9b69ad5c3379836b59df4ee71ef Mon Sep 17 00:00:00 2001 From: Mahmoud Mazouz Date: Fri, 12 Apr 2024 16:26:49 +0200 Subject: [PATCH] feat: Automate Release --- .github/workflows/release.yml | 248 ++++++++++++++-------------------- ci/scripts/build-linux.bash | 41 ++++++ ci/scripts/build-macos.bash | 30 ++++ ci/scripts/bump-and-tag.bash | 25 ++++ ci/scripts/pre-build.bash | 8 ++ 5 files changed, 203 insertions(+), 149 deletions(-) create mode 100644 ci/scripts/build-linux.bash create mode 100644 ci/scripts/build-macos.bash create mode 100644 ci/scripts/bump-and-tag.bash create mode 100644 ci/scripts/pre-build.bash diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f633f9d71..c2a28c74b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,188 +14,138 @@ name: Release on: - release: - types: [published] schedule: - cron: "0 0 * * 1-5" workflow_dispatch: - + inputs: + live-run: + type: boolean + description: Live-run + required: false + version: + type: string + description: Release number + required: false jobs: - preps: - name: Preparation + tag: + name: Branch, Bump & tag runs-on: ubuntu-latest + outputs: + version: ${{ steps.create-release-branch.outputs.version }} + branch: ${{ steps.create-release-branch.outputs.branch }} steps: - - name: Clone this repository + - id: create-release-branch + uses: eclipse-zenoh/ci/create-release-branch@main + with: + repo: ${{ github.repository }} + live-run: ${{ inputs.live-run || false }} + # NOTE(fuzzypixelz): When the version is undefined (e.g. on schedule + # events) we cannot use git-describe as CMake doesn't support it. + # However, we still need some placeholder version to test that the + # version can be reliably bumped. + version: ${{ inputs.version || '0.0.0' }} + github-token: ${{ secrets.BOT_TOKEN_WORKFLOW }} + + - name: Checkout this repository uses: actions/checkout@v4 + with: + ref: ${{ steps.create-release-branch.outputs.branch }} - - name: Environment setup - id: env - shell: bash - run: | - 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}" - echo "GIT_BRANCH=${GIT_BRANCH}" >> $GITHUB_OUTPUT - GIT_TAG=`[[ $GITHUB_REF =~ ^refs/tags/.* ]] && echo ${GITHUB_REF/refs\/tags\//} || true` - echo "GIT_TAG=${GIT_TAG}" - echo "GIT_TAG=${GIT_TAG}" >> $GITHUB_OUTPUT - - ZENOH_VERSION=$(sed -n 's/^project(libzenohpico VERSION \(.*\) LANGUAGES C)/\1/p' CMakeLists.txt | head -n1) - echo "ZENOH_VERSION=${ZENOH_VERSION}" - echo "ZENOH_VERSION=${ZENOH_VERSION}" >> $GITHUB_OUTPUT - if [ -n "${GIT_TAG}" ]; then - IS_RELEASE="true" - echo "IS_RELEASE=${IS_RELEASE}" - echo "IS_RELEASE=${IS_RELEASE}" >> $GITHUB_OUTPUT - PKG_VERSION=${GIT_TAG} - 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}" - echo "PKG_VERSION=${PKG_VERSION}" >> $GITHUB_OUTPUT + - name: Bump and tag project + run: bash ci/scripts/bump-and-tag.bash + env: + VERSION: ${{ steps.create-release-branch.outputs.version }} + GIT_USER_NAME: eclipse-zenoh-bot + GIT_USER_EMAIL: eclipse-zenoh-bot@users.noreply.github.com - CROSSBUILD_TARGETS=$(sed -n 's/^CROSSBUILD_TARGETS=\(.*\)/\1/p' GNUmakefile | head -n1) - echo "CROSSBUILD_TARGETS=$CROSSBUILD_TARGETS" - TARGET_MATRIX="{\"target\": [\"${CROSSBUILD_TARGETS// /\",\"}\"]}" - echo "TARGET_MATRIX=$TARGET_MATRIX" - echo "TARGET_MATRIX=$TARGET_MATRIX" >> $GITHUB_OUTPUT + pre-build: + name: Pre-Build + needs: tag + runs-on: ubuntu-latest 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 }} - TARGET_MATRIX: ${{ steps.env.outputs.TARGET_MATRIX }} + build-linux-matrix: ${{ steps.pre-build.outputs.build-linux-matrix }} + steps: + - name: Clone this repository + uses: actions/checkout@v4 + with: + ref: ${{ needs.tag.outputs.branch }} + + - id: pre-build + run: bash ci/scrips/pre-build.bash - macos-build: - name: Build on macos-x64 - needs: preps + build-macos: + name: Build for macOS (x64) + needs: tag runs-on: macos-latest steps: - name: Clone this repository uses: actions/checkout@v4 + with: + ref: ${{ needs.tag.outputs.branch }} - - name: MacOS build - run: make + - id: build-macos + run: bash ci/scripts/build-macos.bash env: - BUILD_TYPE: RELEASE - - - name: Packaging - id: package - shell: bash - run: | - LIB_PKG_NAME=${PWD}/zenoh-pico-${{ needs.preps.outputs.PKG_VERSION }}-macos-x64.zip - echo "Packaging ${LIB_PKG_NAME}:" - cd build && zip -r ${LIB_PKG_NAME} lib && cd - - zip -r ${LIB_PKG_NAME} include - echo "LIB_PKG_NAME=${LIB_PKG_NAME}" >> $GITHUB_OUTPUT + REPO: ${{ github.repository }} + VERSION: ${{ needs.tag.outputs.version }} - EXP_PKG_NAME=${PWD}/zenoh-pico-${{ needs.preps.outputs.PKG_VERSION }}-macos-x64-examples.zip - echo "Packaging ${EXP_PKG_NAME}:" - cd build/examples && zip ${EXP_PKG_NAME} * && cd - - echo "EXP_PKG_NAME=${EXP_PKG_NAME}" >> $GITHUB_OUTPUT - - - name: "Upload x86_64 macos package" - uses: actions/upload-artifact@v3 + - name: Upload macOS archives + uses: actions/upload-artifact@v4 with: - name: macos-x64 - path: | - ${{ steps.package.outputs.LIB_PKG_NAME }} - ${{ steps.package.outputs.EXP_PKG_NAME }} + name: ${{ steps.build-macos.outputs.archive-name }} + path: ${{ steps.build-macos.outputs.archive-paths }} - linux-builds: + build-linux: name: Crossbuild for ${{ matrix.target }} - needs: preps + needs: [tag, pre-build] runs-on: ubuntu-latest strategy: fail-fast: false - matrix: ${{fromJson(needs.preps.outputs.TARGET_MATRIX)}} + matrix: ${{ fromJson(needs.pre-build.outputs.build-linux-matrix) }} steps: - name: Clone this repository uses: actions/checkout@v4 + with: + ref: ${{ needs.tag.outputs.branch }} - - name: make for ${{ matrix.target }} + - id: build-linux + run: bash ci/scripts/build-linux.bash env: - BUILD_TYPE: RELEASE - run: make ${{ matrix.target }} - - - name: Packaging - id: package - shell: bash - run: | - TARGET=${{ matrix.target }} - LIB_PKG_NAME=${PWD}/zenoh-pico-${{ needs.preps.outputs.PKG_VERSION }}-${TARGET}.zip - DEB_PKG_NAME=${PWD}/zenoh-pico-${{ needs.preps.outputs.PKG_VERSION }}-${TARGET}-deb-pkgs.zip - RPM_PKG_NAME=${PWD}/zenoh-pico-${{ needs.preps.outputs.PKG_VERSION }}-${TARGET}-rpm-pkgs.zip - EXP_PKG_NAME=${PWD}/zenoh-pico-${{ needs.preps.outputs.PKG_VERSION }}-${TARGET}-examples.zip - - echo "Packaging ${LIB_PKG_NAME}:" - cd crossbuilds/${TARGET} && zip -r ${LIB_PKG_NAME} lib && cd - - zip -r ${LIB_PKG_NAME} include - echo "LIB_PKG_NAME=${LIB_PKG_NAME}" >> $GITHUB_OUTPUT - - cd crossbuilds/${TARGET}/packages - echo "Packaging ${DEB_PKG_NAME}:" - zip ${DEB_PKG_NAME} *.deb - echo "DEB_PKG_NAME=${DEB_PKG_NAME}" >> $GITHUB_OUTPUT - echo "Packaging ${RPM_PKG_NAME}:" - zip ${RPM_PKG_NAME} *.rpm - echo "RPM_PKG_NAME=${RPM_PKG_NAME}" >> $GITHUB_OUTPUT - cd - + REPO: ${{ github.repository }} + VERSION: ${{ needs.tag.outputs.version }} + TARGET: ${{ matrix.target }} - echo "Packaging ${EXP_PKG_NAME}:" - cd crossbuilds/${TARGET}/examples && zip ${EXP_PKG_NAME} * && cd - - echo "EXP_PKG_NAME=${EXP_PKG_NAME}" >> $GITHUB_OUTPUT - - - name: "Upload packages" - uses: actions/upload-artifact@v3 + - name: Upload Linux archives for ${{ matrix.target }} + uses: actions/upload-artifact@v4 with: - name: ${{ matrix.target }} - path: | - ${{ steps.package.outputs.LIB_PKG_NAME }} - ${{ steps.package.outputs.DEB_PKG_NAME }} - ${{ steps.package.outputs.RPM_PKG_NAME }} - ${{ steps.package.outputs.EXP_PKG_NAME }} + name: ${{ steps.build-linux.outputs.archive-name }} + path: ${{ steps.build-linux.outputs.archive-paths }} - publication: - name: Publish the release - if: needs.preps.outputs.IS_RELEASE == 'true' - needs: [preps, macos-build, linux-builds] + eclipse: + needs: [tag, build-macos, build-linux] runs-on: ubuntu-latest steps: - - name: Download result of previous builds - uses: actions/download-artifact@v3 + - uses: eclipse-zenoh/ci/publish-crates-eclipse@main with: - path: ARTIFACTS - - - name: Publish as github release - uses: softprops/action-gh-release@v1 + live-run: ${{ inputs.live-run || false }} + version: ${{ needs.tag.outputs.version }} + ssh-host: genie.zenoh@projects-storage.eclipse.org + ssh-host-path: /home/data/httpd/download.eclipse.org/zenoh/zenoh-pico + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + ssh-passphrase: ${{ secrets.SSH_PASSPHRASE }} + archive-patterns: ".*-standalone.zip" + + github: + needs: [tag, build-macos, build-linux] + runs-on: ubuntu-latest + steps: + - uses: eclipse-zenoh/ci/publish-crates-github@main 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-pico - 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.preps.outputs.PKG_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 + repo: ${{ github.repository }} + live-run: ${{ inputs.live-run || false }} + version: ${{ needs.tag.outputs.version }} + branch: ${{ needs.tag.outputs.branch }} + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + ssh-passphrase: ${{ secrets.SSH_PASSPHRASE }} + github-token: ${{ secrets.BOT_TOKEN_WORKFLOW }} + archive-patterns: ".*-standalone.zip" diff --git a/ci/scripts/build-linux.bash b/ci/scripts/build-linux.bash new file mode 100644 index 000000000..81e1d53ad --- /dev/null +++ b/ci/scripts/build-linux.bash @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -xeo pipefail + +# Repository +readonly repo=${REPO:?input REPO is required} +# Release number +readonly version=${VERSION:?input TARGET is required} +# Build target +readonly target=${TARGET:?input TARGET is required} + +BUILD_TYPE=RELEASE make "$target" + +readonly out=$GITHUB_WORKSPACE +readonly repo_name=${repo#*/} +readonly archive_lib=$out/$repo_name-$version-$target.zip +readonly archive_deb=$out/$repo_name-$version-$target-deb-pkgs.zip +readonly archive_rpm=$out/$repo_name-$version-$target-rpm-pkgs.zip +readonly archive_examples=$out/$repo_name-$version-$target-examples.zip + +cd crossbuilds/"$target" +zip -r "$archive_lib" lib +cd - +zip -r "$archive_lib" include + +cd crossbuilds/"$target"/packages +zip "$archive_deb" ./*.deb +zip "$archive_rpm" ./*.rpm +cd - + +cd crossbuilds/"$archive_examples"/examples +zip "$archive_examples" ./* +cd - + +archive_paths=$(printf '%s\n' "$archive_lib") +archive_paths+=$(printf '%s\n' "$archive_deb") +archive_paths+=$(printf '%s\n' "$archive_rpm") +archive_paths+="$archive_examples" + +echo "archive-name=$repo_name-$version-$target-standalone.zip" +echo "archive-paths=$archive_paths" diff --git a/ci/scripts/build-macos.bash b/ci/scripts/build-macos.bash new file mode 100644 index 000000000..c55114dac --- /dev/null +++ b/ci/scripts/build-macos.bash @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -xeo pipefail + +# Repository +readonly repo=${REPO:?input REPO is required} +# Release number +readonly version=${VERSION:?input VERSION is required} + +BUILD_TYPE=RELEASE make + +readonly out=$GITHUB_WORKSPACE +readonly repo_name=${repo#*/} +readonly archive_lib=$out/$repo_name-$version-macos-x64.zip +readonly archive_examples=$out/$repo_name-$version-macos-x64-examples.zip + +cd build +zip -r "$archive_lib" lib +cd .. +zip -r "$archive_lib" include + +cd build/examples +zip "$archive_examples" ./* +cd .. + +archive_paths=$(printf '%s\n' "$archive_lib") +archive_paths+="$archive_examples" + +echo "archive-name=$repo_name-$version-macos-x64-standalone.zip" +echo "archive-paths=$archive_paths" diff --git a/ci/scripts/bump-and-tag.bash b/ci/scripts/bump-and-tag.bash new file mode 100644 index 000000000..4fdeac86e --- /dev/null +++ b/ci/scripts/bump-and-tag.bash @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -eo pipefail + +# Release number +readonly version=${VERSION:-''} +# Git actor name +readonly git_user_name=${GIT_USER_NAME:?input GIT_USER_NAME is required} +# Git actor email +readonly git_user_email=${GIT_USER_EMAIL:?input GIT_USER_EMAIL is required} + +export GIT_AUTHOR_NAME=$git_user_name +export GIT_AUTHOR_EMAIL=$git_user_email +export GIT_COMMITTER_NAME=$git_user_name +export GIT_COMMITTER_EMAIL=$git_user_email + +# Bump CMake project version +printf '%s' "$version" > version.txt + +git commit version.txt -m "chore: Bump version to $version" +git tag "$version" -m "v$version" +git log -10 +git show-ref --tags +git push origin +git push origin "$version" diff --git a/ci/scripts/pre-build.bash b/ci/scripts/pre-build.bash new file mode 100644 index 000000000..0398ea656 --- /dev/null +++ b/ci/scripts/pre-build.bash @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -eo pipefail + +# Extract cross-compilation targets from the Makefile +crossbuild_targets=$(sed -n 's/^CROSSBUILD_TARGETS=\(.*\)/\1/p' GNUmakefile | head -n1) +target_matrix="{\"target\": [\"${crossbuild_targets// /\",\"}\"]}" +echo "build-linux-matrix=$target_matrix" >> "$GITHUB_OUTPUT"