diff --git a/.gitea/workflows/BuildTestPublish.yaml b/.gitea/workflows/BuildTestPublish.yaml new file mode 100644 index 0000000..fb9fbfd --- /dev/null +++ b/.gitea/workflows/BuildTestPublish.yaml @@ -0,0 +1,38 @@ +name: Build-Test-Publish +run-name: Build test and publish all tools + +on: [push] + +defaults: + run: + shell: bash + +jobs: + build: + strategy: + matrix: + platform: + - linux/amd64 + - linux/arm64 + runs-on: ${{ matrix.platform }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Login to Gitea + uses: docker/login-action@v3 + with: + registry: gitea.jde.nz + username: DoesntMatter + password: ${{ secrets.DOCKER_PUSH_TOKEN }} + - name: Build + run: | + ./build.sh + - name: Test + run: | + ./test.sh + - name: Publish + run: | + SOS_WRITE_TOKEN=${{ secrets.SOS_WRITE_TOKEN }} \ + RELEASE_WRITE_TOKEN=${{ secrets.RELEASE_WRITE_TOKEN }} \ + GITEA_CONTAINER_NAME=${{ env.JOB_CONTAINER_NAME }} \ + ./publish.sh \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..03f9081 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +# Build artifacts +output/ +build/ +*.o +*.a + +# Test artifacts +tests/test_lib +tests/test_stress + +# IDE files +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS files +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/README.md b/README.md index fe5f2ff..6609bcd 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,45 @@ Simple SHA256 hashing library and example utility - outputs the hash only with a newline - -v (verbose) mode lists the individual files as they are processed. -# testing +# Installation -- testing of both the C++ class and the dshash utility are in tests/ -- ./test.sh runs all tests and returns success only if all pass. +## Quick install (recommended) -# publishing -- dshash utility published as a getpkg.xyz package, and also available from getbin.xyz. +```bash +curl https://getbin.xyz/dshash-install | bash +``` + +## Manual download + +```bash +# For x86_64 +curl -L -o dshash https://getbin.xyz/dshash:latest-x86_64 + +# For arm64/aarch64 +curl -L -o dshash https://getbin.xyz/dshash:latest-aarch64 + +chmod +x dshash +``` + +## Using getpkg + +```bash +getpkg install dshash +``` + +# Testing + +- Testing of both the C++ class and the dshash utility are in tests/ +- ./test.sh runs all tests and returns success only if all pass +- Comprehensive test suite includes: + - Unit tests for the library + - System sha256sum comparison + - NIST test vectors validation + - Stress tests and edge cases + - Performance benchmarks + +# Publishing + +- dshash utility published as a getpkg.xyz package, and also available from getbin.xyz +- Automated CI/CD via Gitea Actions for linux/amd64 and linux/arm64 diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..03ba109 --- /dev/null +++ b/build.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +PROJECT="$(basename "${SCRIPT_DIR}")" + +rm -rf "${SCRIPT_DIR}/output" +mkdir -p "${SCRIPT_DIR}/output" + +# Build dshash utility +cd "${SCRIPT_DIR}/dshash" +make clean +make + +# Copy binary to output +cp "${SCRIPT_DIR}/dshash/dshash" "${SCRIPT_DIR}/output/dshash" + +# Make sure it's executable +chmod +x "${SCRIPT_DIR}/output/dshash" + +echo "Build complete: ${SCRIPT_DIR}/output/dshash" \ No newline at end of file diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..414e550 --- /dev/null +++ b/install.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +set -euo pipefail + +# Detect architecture +ARCH=$(uname -m) +case "$ARCH" in + x86_64) + ARCH="x86_64" + ;; + aarch64|arm64) + ARCH="aarch64" + ;; + *) + echo "Unsupported architecture: $ARCH" + exit 1 + ;; +esac + +# Detect OS +OS=$(uname -s | tr '[:upper:]' '[:lower:]') +if [ "$OS" != "linux" ]; then + echo "This installer only supports Linux. Detected OS: $OS" + exit 1 +fi + +# Set installation directory +INSTALL_DIR="${HOME}/.local/bin" +INSTALL_PATH="${INSTALL_DIR}/dshash" + +# Create installation directory if it doesn't exist +mkdir -p "${INSTALL_DIR}" + +# Download dshash binary +echo "Downloading dshash for ${OS}/${ARCH}..." +DOWNLOAD_URL="https://getbin.xyz/dshash:latest-${ARCH}" + +if command -v curl >/dev/null 2>&1; then + curl -L -s -o "${INSTALL_PATH}" "${DOWNLOAD_URL}" +elif command -v wget >/dev/null 2>&1; then + wget -q -O "${INSTALL_PATH}" "${DOWNLOAD_URL}" +else + echo "Error: Neither curl nor wget is available. Please install one of them." + exit 1 +fi + +# Make it executable +chmod +x "${INSTALL_PATH}" + +# Verify installation +if "${INSTALL_PATH}" /dev/null 2>/dev/null; then + echo "dshash has been successfully installed to ${INSTALL_PATH}" + + # Check if directory is in PATH + if [[ ":$PATH:" != *":${INSTALL_DIR}:"* ]]; then + echo "" + echo "Note: ${INSTALL_DIR} is not in your PATH." + echo "Add the following line to your shell configuration file (.bashrc, .zshrc, etc.):" + echo " export PATH=\"${INSTALL_DIR}:\$PATH\"" + fi +else + echo "Error: Installation verification failed" + exit 1 +fi + +echo "" +echo "Installation complete! You can now use 'dshash' to compute SHA256 hashes." +echo "Usage: dshash [-v] " \ No newline at end of file diff --git a/publish.sh b/publish.sh new file mode 100755 index 0000000..b571261 --- /dev/null +++ b/publish.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +ARCH=$(uname -m) +PROJECT="$(basename "${SCRIPT_DIR}")" +OUTPUT="${SCRIPT_DIR}/output" + +function heading() { + echo "--------------------------------" + echo "$1" + echo "--------------------------------" +} + +#-------------------------------------------------------------------------------- +heading "Publishing ${PROJECT}" + +function die() { + heading "error: $1" + exit 1 +} + +[[ -n ${SOS_WRITE_TOKEN:-} ]] || die "SOS_WRITE_TOKEN not specified" + +# clear output dir +rm -rf "${OUTPUT}" +mkdir -p "${OUTPUT}" + +#-------------------------------------------------------------------------------- +heading "Building ${PROJECT}" + +# build release version +"${SCRIPT_DIR}/build.sh" +[ -f "${OUTPUT}/${PROJECT}" ] || die "Build failed." + +# install getpkg +GETPKG_PATH="${HOME}/.local/bin/getpkg/getpkg" +if [ ! -f "${GETPKG_PATH}" ]; then + heading "Installing getpkg" + curl https://getbin.xyz/getpkg-install | bash + if [ ! -f "${GETPKG_PATH}" ]; then + die "getpkg failed to install to ${GETPKG_PATH}" + fi +fi + +#-------------------------------------------------------------------------------- +heading "Publishing ${PROJECT} as tool to ${PROJECT}:${ARCH} (on getpkg.xyz)" + +TOOLDIR="${OUTPUT}/tool" +mkdir "${TOOLDIR}" +cp "${OUTPUT}/${PROJECT}" "${TOOLDIR}/${PROJECT}" +"${GETPKG_PATH}" server set-token getpkg.xyz "${SOS_WRITE_TOKEN}" +"${GETPKG_PATH}" publish "${PROJECT}:${ARCH}" "${TOOLDIR}" + +#-------------------------------------------------------------------------------- +heading "Publishing ${PROJECT} to getbin.xyz" + +# Download sos if not already present +SOS="${OUTPUT}/sos" +if [ ! -f "${SOS}" ]; then + heading "Downloading sos tool" + curl -L -s -o "${SOS}" "https://getbin.xyz/sos:latest" || die "Failed to download sos" + chmod +x "${SOS}" +fi + +# Upload architecture-specific binary to getbin.xyz +heading "Uploading ${PROJECT} binary to getbin.xyz as ${PROJECT}:latest-${ARCH}" +"${SOS}" upload "getbin.xyz" "${OUTPUT}/${PROJECT}" "${PROJECT}:latest-${ARCH}" || die "Failed to upload ${PROJECT} binary to getbin.xyz" + +# Check if there's an install script to upload +if [ -f "${SCRIPT_DIR}/install.sh" ]; then + heading "Uploading install.sh to getbin.xyz as ${PROJECT}-install:latest" + "${SOS}" upload "getbin.xyz" "${SCRIPT_DIR}/install.sh" "${PROJECT}-install:latest" || die "Failed to upload install script to getbin.xyz" +fi + +heading "Successfully published ${PROJECT} to both getpkg.xyz and getbin.xyz" \ No newline at end of file diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..a92d7f3 --- /dev/null +++ b/test.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +# Run the comprehensive test suite +"${SCRIPT_DIR}/tests/test.sh" \ No newline at end of file