diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml index 318b333..ff55084 100644 --- a/.github/actions/build/action.yml +++ b/.github/actions/build/action.yml @@ -17,9 +17,15 @@ runs: steps: - name: Convert input targets to Bash array + # read comma-separated list of targets, converts it to + # an array of arguments for cargo-zigbuild like this: + # [ "--target", "", "--target", "", ... ] shell: bash run: | - readarray -d $'\0' -t targets < <(awk -F, '{ for (i = 1; i <= NF; i++) printf "--target\0%s\0", $i }' <<< "${{ inputs.targets }}") + targets=() + while IFS=',' read -r target + do targets+=("--target" "$target") + done <<< "${{ inputs.targets }}" declare -p targets > /tmp/targets.sh - name: Check with cargo-fmt @@ -27,7 +33,7 @@ runs: shell: sh run: cargo fmt -v --all -- --check - - name: Run Clippy + - name: Run Clippy with cargo-zigbuild if: inputs.lint == true shell: bash run: | diff --git a/.github/actions/dependencies/action.yml b/.github/actions/dependencies/action.yml index 5095cce..17635f9 100644 --- a/.github/actions/dependencies/action.yml +++ b/.github/actions/dependencies/action.yml @@ -12,6 +12,13 @@ runs: - name: Install Zig shell: bash + # the `--transform` options are used to install Zig in the /usr/local/: + # */zig -> /usr/local/bin/zig + # */lib/ -> /usr/local/lib/zig/ + # the rest is not really necessary, but for consistency: + # */doc/ -> /usr/local/share/doc/zig/ + # */LICENSE -> /usr/local/share/doc/zig/copyright + # */README.md -> /usr/local/share/doc/zig/README.md run: | ZIG_VERSION="${{ inputs.zig-version }}" [ "$RUNNER_ARCH" == "X64" ] && ZIG_ARCH="x86_64" || ZIG_ARCH="aarch64" diff --git a/.github/scripts/compress-artifact.sh b/.github/scripts/compress-artifact.sh deleted file mode 100755 index db4f9cb..0000000 --- a/.github/scripts/compress-artifact.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -BINARY_FILE="target/$1/release/sculptor" -COMMON_FILES=("Config.example.toml") -ARTIFACT_OUTPUT="${OUTPUT_DIR}/sculptor-$2-$3" -if [ "$2" = "windows" ] -then zip -j "${ARTIFACT_OUTPUT}.zip" "${BINARY_FILE}.exe" "${COMMON_FILES[@]}" -else tar --transform 's|^.*/||' -czf "${ARTIFACT_OUTPUT}.tar.gz" "$BINARY_FILE" "${COMMON_FILES[@]}" -fi \ No newline at end of file diff --git a/.github/scripts/package-artifacts.sh b/.github/scripts/package-artifacts.sh index 4b380bc..28868e0 100755 --- a/.github/scripts/package-artifacts.sh +++ b/.github/scripts/package-artifacts.sh @@ -1,12 +1,64 @@ #!/bin/bash set -euo pipefail +USAGE="\ +Usage: $0 [-t target]... [-o output_dir] [-h] + -t target add a build target + -o output_dir set output directory for compressed files (default: current directory) + -h Show this help message and exit -export OUTPUT_DIR -mkdir -p "$OUTPUT_DIR" +Environment variables (override options): + OUTPUT_DIR output directory for compressed files + CARGO_BUILD_TARGETS comma-separated list of targets +" +targets=() +output_dir= -printenv CARGO_BUILD_TARGETS | awk -F, '{ - for (i = 1; i <= NF; i++) - if (match($i, /^([^-]+)(-[^-]+)*-(linux|windows|darwin)(-[^-]+)*$/, matches)) - printf "%s\0%s\0%s\0", $i, matches[3], matches[1] - else print "DEBUG: awk: No regex match for field index " i ": \047" $i "\047" > /dev/stderr -}' | xargs -0 -n 3 "$(dirname -- "$(readlink -f -- "$0")")/compress-artifact.sh" \ No newline at end of file +while getopts "t:o:h" opt +do + case $opt in + t) targets+=("$OPTARG") ;; + o) output_dir="$OPTARG" ;; + h) echo "$USAGE"; exit 0 ;; + *) echo "Invalid option: ${opt}" >&2; echo "$USAGE"; exit 1 ;; + esac +done + +output_dir="${OUTPUT_DIR:-${output_dir:-.}}" + +if [ "${CARGO_BUILD_TARGETS+set}" ] # if set (might be empty) +then IFS=',' read -ra targets <<< "$CARGO_BUILD_TARGETS" +fi + +compress-artifact() { + local build_dir os arch binary_file common_files output_file + + build_dir="$1" + os="$2" + arch="$3" + + binary_file="${build_dir}/sculptor" + # can be extended to include more files if needed + common_files=("Config.example.toml") + output_file="${output_dir}/sculptor-${os}-${arch}" + + if [ "$2" = "windows" ] + then zip -j "${output_file}.zip" "${binary_file}.exe" "${common_files[@]}" + else tar --transform 's|^.*/||' -czf "${output_file}.tar.gz" "$binary_file" "${common_files[@]}" + fi +} + +for target in "${targets[@]}" +do + build_dir="target/${target}/release" + # add more targets as needed, for now only linux and windows + if [[ "$target" =~ ^([^-]+)(-[^-]+)*-(linux|windows)(-[^-]+)*$ ]] + then + os="${BASH_REMATCH[3]}" + arch="${BASH_REMATCH[1]}" + declare -p BASH_REMATCH + echo compress-artifact "$build_dir" "$os" "$arch" + else + echo "ERROR: Invalid target: $target" >&2 + exit 1 + fi +done \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b365bbc..f0065e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,12 +7,16 @@ on: - src - Cargo* - Dockerfile + # this file + - .github/workflows/ci.yml pull_request: branches: [ "master" ] paths: - src - Cargo* - Dockerfile + # this file + - .github/workflows/ci.yml permissions: contents: read @@ -28,6 +32,7 @@ jobs: runs-on: ubuntu-latest env: OUTPUT_DIR: target/output + # in case we wanted to test multiple toolchains: strategy: matrix: toolchain: @@ -63,7 +68,8 @@ jobs: targets: ${{ env.CARGO_BUILD_TARGETS }} - name: Package the artifacts - run: ./.github/scripts/package-artifacts.sh + run: mkdir -p "$OUTPUT_DIR" && \ + ./.github/scripts/package-artifacts.sh - name: Upload the artifacts uses: actions/upload-artifact@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a864454..28793ca 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,6 +41,7 @@ jobs: with: toolchain: ${{ env.RUST_VERSION }} targets: ${{ env.CARGO_BUILD_TARGETS }} + # needed if we want to use linting in build action # components: clippy, rustfmt - name: Install the build dependencies @@ -56,7 +57,8 @@ jobs: lint: false - name: Package the artifacts - run: ./.github/scripts/package-artifacts.sh + run: mkdir -p "$OUTPUT_DIR" && \ + ./.github/scripts/package-artifacts.sh - name: Upload artifact id: artifact-upload @@ -73,11 +75,13 @@ jobs: - name: Checkout the code uses: actions/checkout@v4 + # if we wanted to push to DockerHub: # - name: Login to DockerHub # uses: docker/login-action@v3 # with: # username: ${{ secrets.DOCKERHUB_USERNAME }} # password: ${{ secrets.DOCKERHUB_TOKEN }} + # also uncomment the tags parameter in the last step # - name: Login to GitHub Container Registry # uses: docker/login-action@v3 @@ -105,7 +109,6 @@ jobs: tags: | ghcr.io/${{ github.repository_owner }}/sculptor:latest ghcr.io/${{ github.repository_owner }}/sculptor:${{ github.ref_name }} - # If we were to push to DockerHub: # ${{ github.repository_owner }}/sculptor:latest # ${{ github.repository_owner }}/sculptor:${{ github.ref_name }} provenance: false @@ -132,16 +135,6 @@ jobs: with: artifact-ids: ${{ needs.build-binary.outputs.binary-artifact-id }} - - name: Debug tag information - shell: bash - run: | - echo "Workflow triggered by GITHUB_REF_NAME: ${{ github.ref_name }}" - echo "--- Listing all local tags ---" - git tag -l - echo "--- Showing details for tag '${{ github.ref_name }}' ---" - git show ${{ github.ref_name }} || echo "Error: Tag '${{ github.ref_name }}' not found or 'git show' failed." - echo "--------------------------------" - - name: Create release env: GH_TOKEN: ${{ github.token }}