diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 7fa316a..26bca8f 100755 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -37,7 +37,7 @@ jobs: name: artifacts path: artifacts - build-release: + build-release-artifacts: name: build-release needs: [create-github-release] runs-on: ${{ matrix.job.os }} @@ -48,15 +48,16 @@ jobs: matrix: rust: [stable] job: - - { os: "macOS-latest", target: "x86_64-apple-darwin", artifact_prefix: "macos" } - - { os: "windows-latest", target: "x86_64-pc-windows-msvc", artifact_prefix: "windows" } - - { os: "ubuntu-latest", target: "x86_64-unknown-linux-gnu", artifact_prefix: "linux", } + - { name: "macOS-arm64", os: "macOS-latest", target: "aarch64-apple-darwin", artifact_prefix: "macos-arm64", use-cross: true } + - { name: "macOS-amd64", os: "macOS-latest", target: "x86_64-apple-darwin", artifact_prefix: "macos" } + - { name: "windows-amd64", os: "windows-latest", target: "x86_64-pc-windows-msvc", artifact_prefix: "windows" } + - { name: "linux-gnu", os: "ubuntu-latest", target: "x86_64-unknown-linux-gnu", artifact_prefix: "linux", } # seems impossible to build static musl binaries due to XCB dependency. See https://github.com/rust-lang/rust/issues/116348 - # - { os: "ubuntu-latest", target: "x86_64-unknown-linux-musl", artifact_prefix: "linux-musl", } - - { os: "ubuntu-latest", target: "aarch64-unknown-linux-gnu", artifact_prefix: "aarch64-gnu", use-cross: true, test-bin: "--bin jwtui" } - - { os: "ubuntu-latest", target: "aarch64-unknown-linux-musl", artifact_prefix: "aarch64-musl", use-cross: true, test-bin: "--bin jwtui" } - - { os: "ubuntu-latest", target: "arm-unknown-linux-gnueabihf", artifact_prefix: "arm-gnu", use-cross: true, test-bin: "--bin jwtui" } - - { os: "ubuntu-latest", target: "arm-unknown-linux-musleabihf", artifact_prefix: "arm-musl", use-cross: true, test-bin: "--bin jwtui" } + # { name: "linux-musl", os: "ubuntu-latest", target: "x86_64-unknown-linux-musl", artifact_prefix: "linux-musl", } + - { name: "aarch64-gnu", os: "ubuntu-latest", target: "aarch64-unknown-linux-gnu", artifact_prefix: "aarch64-gnu", use-cross: true, test-bin: "--bin jwtui" } + - { name: "aarch64-musl", os: "ubuntu-latest", target: "aarch64-unknown-linux-musl", artifact_prefix: "aarch64-musl", use-cross: true, test-bin: "--bin jwtui" } + - { name: "arm-gnu", os: "ubuntu-latest", target: "arm-unknown-linux-gnueabihf", artifact_prefix: "arm-gnu", use-cross: true, test-bin: "--bin jwtui" } + - { name: "arm-musl", os: "ubuntu-latest", target: "arm-unknown-linux-musleabihf", artifact_prefix: "arm-musl", use-cross: true, test-bin: "--bin jwtui" } steps: - name: Checkout repository @@ -111,7 +112,13 @@ jobs: args: --release --verbose --target=${{ matrix.job.target }} toolchain: ${{ matrix.rust }} + - name: Verify file + shell: bash + run: | + file target/${{ matrix.job.target }}/release/jwtui + - name: Test + if: matrix.job.target != 'aarch64-apple-darwin' uses: actions-rs/cargo@v1 with: use-cross: ${{ matrix.job.use-cross }} @@ -171,8 +178,8 @@ jobs: name: artifacts path: artifacts - publish-package-formula: - needs: [build-release] + publish-homebrew-formula: + needs: [build-release-artifacts] name: Update homebrew & scoop formulas runs-on: ubuntu-latest steps: @@ -192,24 +199,24 @@ jobs: run: | macos_sha="$(cat ./artifacts/jwtui-macos.sha256 | awk '{print $1}')" echo "MACOS_SHA=$macos_sha" >> $GITHUB_ENV + macos_sha_arm="$(cat ./artifacts/jwtui-macos-arm64.sha256 | awk '{print $1}')" + echo "MACOS_SHA_ARM=$macos_sha_arm" >> $GITHUB_ENV linux_sha="$(cat ./artifacts/jwtui-linux.sha256 | awk '{print $1}')" echo "LINUX_SHA=$linux_sha" >> $GITHUB_ENV - windows_sha="$(cat ./artifacts/jwtui-windows.sha256 | awk '{print $1}')" - echo "WINDOWS_SHA=$windows_sha" >> $GITHUB_ENV release_version="$(cat ./artifacts/release-version)" echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV - name: Validate release environment variables run: | echo "Release SHA macos: ${{ env.MACOS_SHA }}" + echo "Release SHA macos-arm: ${{ env.MACOS_SHA_ARM }}" echo "Release SHA linux: ${{ env.LINUX_SHA }}" - echo "Release SHA windows: ${{ env.WINDOWS_SHA }}" echo "Release version: ${{ env.RELEASE_VERSION }}" - name: Execute Homebrew packaging script run: | # run packaging script - python "./deployment/homebrew/packager.py" ${{ env.RELEASE_VERSION }} "./deployment/homebrew/jwt-ui.rb.template" "./jwt-ui.rb" ${{ env.MACOS_SHA }} ${{ env.LINUX_SHA }} + python "./deployment/homebrew/packager.py" ${{ env.RELEASE_VERSION }} "./deployment/homebrew/jwt-ui.rb.template" "./jwt-ui.rb" ${{ env.MACOS_SHA }} ${{ env.MACOS_SHA_ARM }} ${{ env.LINUX_SHA }} # push to Git git config --global user.email "d4udts@gmail.com" @@ -222,6 +229,35 @@ jobs: git diff-index --quiet HEAD || git commit -am "Update formula for jwt-ui release ${{ env.RELEASE_VERSION }}" git push origin main + publish-scoop-formula: + needs: [build-release-artifacts] + name: Update scoop formulas + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + fetch-depth: 1 + + - name: Get release artifacts + uses: actions/download-artifact@v2 + with: + name: artifacts + path: artifacts + + - name: Set release assets and version + shell: bash + run: | + windows_sha="$(cat ./artifacts/jwtui-windows.sha256 | awk '{print $1}')" + echo "WINDOWS_SHA=$windows_sha" >> $GITHUB_ENV + release_version="$(cat ./artifacts/release-version)" + echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV + + - name: Validate release environment variables + run: | + echo "Release SHA windows: ${{ env.WINDOWS_SHA }}" + echo "Release version: ${{ env.RELEASE_VERSION }}" + - name: Execute Scoop packaging script run: | # run packaging script @@ -239,6 +275,7 @@ jobs: git push origin main publish-cargo: + needs: [build-release-artifacts] name: Publishing to Cargo runs-on: ubuntu-latest steps: @@ -257,7 +294,7 @@ jobs: args: --token ${{ secrets.CARGO_API_KEY }} --allow-dirty publish-docker-image: - needs: [build-release] + needs: [build-release-artifacts] name: Publishing Docker image to Docker Hub runs-on: ubuntu-latest steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a7fffe..cc4418d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased - 2023-XX-YY +## [1.0.5] - 2024-01-18 + +- macOS arm64 support + ## [1.0.4] - 2024-01-15 - Improved error handling diff --git a/Cargo.lock b/Cargo.lock index 06af97a..bdff5ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -501,7 +501,7 @@ dependencies = [ [[package]] name = "jwt-ui" -version = "1.0.4" +version = "1.0.5" dependencies = [ "backtrace", "cargo-husky", diff --git a/Cargo.toml b/Cargo.toml index 00e1b86..dd8f575 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "jwt-ui" -version = "1.0.4" +version = "1.0.5" authors = ["Deepu K Sasidharan "] description = """ A Terminal UI for decoding/encoding JSON Web Tokens diff --git a/README.md b/README.md index c4269bf..dc0bd70 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,8 @@ If you are looking for a non TUI CLI, check out [jwt-cli](https://github.com/mik ## Limitations/Known issues - Copy to clipboard is not supported on `aarch64` and `arm` machines. +- [macOS] KDash looks better on iTerm2 since macOS's default Terminal app makes the colors render weird. +- [Windows] KDash looks better on CMD since Powershell's default theme makes the colors look weird. ## Libraries used diff --git a/deployment/getLatest.sh b/deployment/getLatest.sh index b0576ae..e99bcce 100755 --- a/deployment/getLatest.sh +++ b/deployment/getLatest.sh @@ -13,104 +13,121 @@ EXE_FILENAME="jwtui" EXE_DEST_DIR="/usr/local/bin" bye() { - result=$? - if [ "$result" != "0" ]; then - echo "Fail to install ${GITHUB_USER}/${GITHUB_REPO}" - fi - exit $result + result=$? + if [ "$result" != "0" ]; then + echo "Fail to install ${GITHUB_USER}/${GITHUB_REPO}" + fi + exit $result } fail() { - echo "$1" - exit 1 + echo "$1" + exit 1 } find_download_url() { - local SUFFIX=$1 - local LATEST_URL="https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/releases/latest" - local URL=$(curl -s "${LATEST_URL}" | grep "browser_download_url.*${SUFFIX}" | cut -d : -f 2,3 | - tr -d \" | - head -n 1) - echo "${URL//[[:space:]]/}" + local SUFFIX=$1 + local LATEST_URL="https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/releases/latest" + local URL=$(curl -s "${LATEST_URL}" | grep "browser_download_url.*${SUFFIX}" | cut -d : -f 2,3 | tr -d \" | head -n 1) + echo "${URL//[[:space:]]/}" } find_arch() { - local ARCH=$(uname -m) - case $ARCH in - armv5*) ARCH="armv5" ;; - armv6*) ARCH="armv6" ;; - armv7*) ARCH="armv7" ;; - aarch64) ARCH="arm64" ;; - x86) ARCH="386" ;; - # x86_64) ARCH="amd64";; - i686) ARCH="386" ;; - i386) ARCH="386" ;; - esac - echo $ARCH + local ARCH=$(uname -m) + + case $ARCH in + armv*) ARCH="arm" ;; + arm64) ARCH="arm64" ;; + aarch64) ARCH="aarch64" ;; + x86_64) ARCH="amd64" ;; + *) fail "Your system architecture is not supported: $ARCH" ;; + esac + + echo $ARCH } find_os() { - local OS=$(echo $(uname) | tr '[:upper:]' '[:lower:]') - - case "$OS" in - # Minimalist GNU for Windows - mingw*) OS='windows' ;; - msys*) OS='windows' ;; - esac - echo $OS + local OS=$(echo $(uname) | tr '[:upper:]' '[:lower:]') + + case "$OS" in + # Minimalist GNU for Windows + mingw*) OS='windows' ;; + msys*) OS='windows' ;; + esac + + echo $OS } find_suffix() { - local OS=$2 - local SUFFIX="$OS.tar.gz" - echo $SUFFIX + local ARCH=$1 + local OS=$2 + local SUFFIX="$OS.tar.gz" + + case "$OS" in + "darwin") + case "$ARCH" in + "arm64") SUFFIX="macos-arm64.tar.gz" ;; + *) SUFFIX='macos.tar.gz' ;; + esac + ;; + "windows") SUFFIX='windows.tar.gz' ;; + *) + case "$ARCH" in + "arm") SUFFIX="arm-gnu.tar.gz" ;; + "aarch64") SUFFIX="aarch64-gnu.tar.gz" ;; + *) SUFFIX='linux.tar.gz' ;; + esac + ;; + esac + + echo $SUFFIX } download_file() { - local FILE_URL="$1" - local FILE_PATH="$2" - echo "Getting $FILE_URL ....." - httpStatusCode=$(curl -s -w '%{http_code}' -L "$FILE_URL" -o "$FILE_PATH") - if [ "$httpStatusCode" != 200 ]; then - echo "failed to download '${URL}'" - fail "Request fail with http status code $httpStatusCode" - fi + local FILE_URL="$1" + local FILE_PATH="$2" + echo "Getting $FILE_URL ....." + httpStatusCode=$(curl -s -w '%{http_code}' -L "$FILE_URL" -o "$FILE_PATH") + if [ "$httpStatusCode" != 200 ]; then + echo "failed to download '${URL}'" + fail "Request fail with http status code $httpStatusCode" + fi } find_exec_dest_path() { - if [ ! -w $EXE_DEST_DIR ]; then - echo "Cannot write to ${EXE_DEST_DIR}. Run with 'sudo' to install to ${EXE_DEST_DIR}. Installing to current directory now ....." - EXE_DEST_DIR=$(pwd) - fi + if [ ! -w $EXE_DEST_DIR ]; then + echo "Cannot write to ${EXE_DEST_DIR}. Run with 'sudo' to install to ${EXE_DEST_DIR}. Installing to current directory now ....." + EXE_DEST_DIR=$(pwd) + fi } install_file() { - local FILE_PATH=$1 - local EXE_DEST_FILE=$2 - TMP_DIR="/tmp/${GITHUB_USER}_${GITHUB_REPO}" - mkdir -p "$TMP_DIR" || true - tar xf "$FILE_PATH" -C "$TMP_DIR" - cp "$TMP_DIR/${EXE_FILENAME}" "${EXE_DEST_FILE}" - chmod +x "${EXE_DEST_FILE}" - rm -rf "$TMP_DIR" + local FILE_PATH=$1 + local EXE_DEST_FILE=$2 + TMP_DIR="/tmp/${GITHUB_USER}_${GITHUB_REPO}" + mkdir -p "$TMP_DIR" || true + tar xf "$FILE_PATH" -C "$TMP_DIR" + cp "$TMP_DIR/${EXE_FILENAME}" "${EXE_DEST_FILE}" + chmod +x "${EXE_DEST_FILE}" + rm -rf "$TMP_DIR" } main() { - find_exec_dest_path - local EXE_DEST_FILE="${EXE_DEST_DIR}/${EXE_FILENAME}" - local ARCH=$(find_arch) - local OS=$(find_os) - local SUFFIX=$(find_suffix $ARCH $OS) - local FILE_URL=$(find_download_url $SUFFIX) - if [ -z "${FILE_URL}" ]; then - fail "Did not find a latest release for your system: $OS $ARCH ($SUFFIX)" - fi - local FILE_PATH="/tmp/${GITHUB_USER}-${GITHUB_REPO}-latest-${SUFFIX}" - download_file "${FILE_URL}" "${FILE_PATH}" - install_file "${FILE_PATH}" "${EXE_DEST_FILE}" - rm -Rf ${FILE_PATH} - echo "executable installed at ${EXE_DEST_FILE}" - bye + find_exec_dest_path + local EXE_DEST_FILE="${EXE_DEST_DIR}/${EXE_FILENAME}" + local ARCH=$(find_arch) + local OS=$(find_os) + local SUFFIX=$(find_suffix $ARCH $OS) + local FILE_URL=$(find_download_url $SUFFIX) + if [ -z "${FILE_URL}" ]; then + fail "Did not find a latest release for your system: $OS $ARCH ($SUFFIX)" + fi + local FILE_PATH="/tmp/${GITHUB_USER}-${GITHUB_REPO}-latest-${SUFFIX}" + download_file "${FILE_URL}" "${FILE_PATH}" + install_file "${FILE_PATH}" "${EXE_DEST_FILE}" + rm -Rf ${FILE_PATH} + echo "executable installed at ${EXE_DEST_FILE}" + bye } #TODO check bash is used `readlink /proc/$$/exe` diff --git a/deployment/homebrew/jwt-ui.rb.template b/deployment/homebrew/jwt-ui.rb.template index 30da617..4d6f4d0 100755 --- a/deployment/homebrew/jwt-ui.rb.template +++ b/deployment/homebrew/jwt-ui.rb.template @@ -4,7 +4,10 @@ class JwtUi < Formula desc "A Terminal UI for decoding/encoding JSON Web Tokens" homepage "https://github.com/jwt-rs/jwt-ui" - if OS.mac? + if OS.mac? and Hardware::CPU.arm? + url "https://github.com/jwt-rs/jwt-ui/releases/download/$version/jwtui-macos-arm64.tar.gz" + sha256 "$hash_mac_arm" + elsif OS.mac? and Hardware::CPU.intel? url "https://github.com/jwt-rs/jwt-ui/releases/download/$version/jwtui-macos.tar.gz" sha256 "$hash_mac" else diff --git a/deployment/homebrew/packager.py b/deployment/homebrew/packager.py index 99dd7a0..55f95e0 100755 --- a/deployment/homebrew/packager.py +++ b/deployment/homebrew/packager.py @@ -9,18 +9,20 @@ # Deployment files hash_mac = args[4].strip() -hash_linux = args[5].strip() +hash_mac_arm = args[5].strip() +hash_linux = args[6].strip() print("Generating formula") print(" VERSION: %s" % version) print(" TEMPLATE PATH: %s" % template_file_path) print(" SAVING AT: %s" % generated_file_path) print(" MAC HASH: %s" % hash_mac) +print(" MAC ARM HASH: %s" % hash_mac_arm) print(" LINUX HASH: %s" % hash_linux) with open(template_file_path, "r") as template_file: template = Template(template_file.read()) - substitute = template.safe_substitute(version=version, hash_mac=hash_mac, hash_linux=hash_linux) + substitute = template.safe_substitute(version=version, hash_mac=hash_mac, hash_mac_arm=hash_mac_arm, hash_linux=hash_linux) print("\n================== Generated package file ==================\n") print(substitute) print("\n============================================================\n")