--- # yaml-language-server: $schema=https://json.schemastore.org/github-action.json name: Setup Test Environment description: Common setup for test jobs (Python, Node, system tools, ShellSpec) inputs: install-act: description: Whether to install act for integration tests required: false default: 'false' install-kcov: description: Whether to build and install kcov from source for coverage (v42) required: false default: 'false' runs: using: composite steps: - name: Install uv uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b # v7.3.0 with: enable-cache: true - name: Set up Python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version-file: pyproject.toml - name: Install Python dependencies shell: bash run: uv sync --frozen - name: Setup Node.js uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: '24' cache: npm - name: Install Node dependencies shell: bash run: npm ci - name: Install system tools shell: bash run: | sudo apt-get update sudo apt-get install -y --no-install-recommends jq shellcheck - name: Install kcov from source if: inputs.install-kcov == 'true' shell: bash run: | echo "Installing kcov build dependencies..." sudo apt-get install -y --no-install-recommends \ cmake \ libcurl4-openssl-dev \ libdw-dev \ libelf-dev \ libiberty-dev \ pkg-config \ zlib1g-dev echo "Building kcov from source..." cd /tmp git clone --depth 1 --branch v42 https://github.com/SimonKagstrom/kcov.git cd kcov mkdir build cd build cmake .. make sudo make install cd / rm -rf /tmp/kcov echo "Verifying kcov installation..." kcov --version - name: Install ShellSpec shell: bash run: | set -euo pipefail # Pin to specific version to avoid supply-chain risks SHELLSPEC_VERSION="0.28.1" SHELLSPEC_URL="https://github.com/shellspec/shellspec/archive/refs/tags/${SHELLSPEC_VERSION}.tar.gz" # Pinned SHA-256 checksum for ShellSpec 0.28.1 # Source: https://github.com/shellspec/shellspec/archive/refs/tags/0.28.1.tar.gz EXPECTED_CHECKSUM="400d835466429a5fe6c77a62775a9173729d61dd43e05dfa893e8cf6cb511783" echo "Downloading ShellSpec ${SHELLSPEC_VERSION}..." curl -fsSL "${SHELLSPEC_URL}" -o "/tmp/shellspec.tar.gz" echo "Verifying checksum..." ACTUAL_CHECKSUM="$(sha256sum /tmp/shellspec.tar.gz | awk '{print $1}')" if [[ "${ACTUAL_CHECKSUM}" != "${EXPECTED_CHECKSUM}" ]]; then echo "Error: Checksum mismatch for ShellSpec ${SHELLSPEC_VERSION}" >&2 echo "Expected: ${EXPECTED_CHECKSUM}" >&2 echo "Got: ${ACTUAL_CHECKSUM}" >&2 rm -f /tmp/shellspec.tar.gz exit 1 fi echo "Checksum verified successfully" echo "Installing ShellSpec..." mkdir -p ~/.local/lib tar -xzf /tmp/shellspec.tar.gz -C ~/.local/lib mv ~/.local/lib/shellspec-${SHELLSPEC_VERSION} ~/.local/lib/shellspec rm /tmp/shellspec.tar.gz sudo ln -s ~/.local/lib/shellspec/shellspec /usr/local/bin/shellspec - name: Install act if: inputs.install-act == 'true' shell: bash run: | set -euo pipefail # Pin to specific version to avoid supply-chain risks ACT_VERSION="0.2.82" ACT_ARCH="Linux_x86_64" ACT_TARBALL="act_${ACT_ARCH}.tar.gz" ACT_URL="https://github.com/nektos/act/releases/download/v${ACT_VERSION}/${ACT_TARBALL}" ACT_CHECKSUM_URL="https://github.com/nektos/act/releases/download/v${ACT_VERSION}/checksums.txt" echo "Downloading act v${ACT_VERSION}..." curl -fsSL "${ACT_URL}" -o "/tmp/${ACT_TARBALL}" echo "Downloading checksums..." curl -fsSL "${ACT_CHECKSUM_URL}" -o "/tmp/act-checksums.txt" echo "Verifying checksum..." # Extract the checksum for our specific file and verify # Use cd to match the filename format in checksums.txt cd /tmp if ! grep "${ACT_TARBALL}" act-checksums.txt | sha256sum -c -; then echo "Error: Checksum verification failed for ${ACT_TARBALL}" >&2 rm -f "${ACT_TARBALL}" act-checksums.txt exit 1 fi echo "Checksum verified successfully" echo "Installing act..." tar -xzf "${ACT_TARBALL}" -C /tmp sudo install -m 755 /tmp/act /usr/local/bin/act rm -f "${ACT_TARBALL}" /tmp/act act-checksums.txt echo "Verifying act installation..." act --version - name: Setup Docker and act configuration if: inputs.install-act == 'true' shell: bash run: | # Ensure Docker is running docker ps > /dev/null 2>&1 || (echo "Docker is not running" && exit 1) # Pre-pull the act Docker image to avoid interactive prompts docker pull catthehacker/ubuntu:act-latest - name: Verify tools shell: bash run: | shellspec --version jq --version uv --version if [[ "${{ inputs.install-act }}" == "true" ]]; then act --version docker --version fi