diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..03d57c5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM mineunit/mineunit:latest + +USER root +ENV USER=root + +RUN apk add --no-cache bash + +COPY scripts /scripts +RUN chmod -R +x /scripts + +ENTRYPOINT ["/scripts/entrypoint.sh"] diff --git a/README.md b/README.md index a542afd..db045ea 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # mineunit-actions + GitHub actions for mt-mods/mineunit -Executes Lua unit tests with `busted` in `spec` directory with code coverage analysis using `cluacov` and generates badge for coverage. +Executes Lua unit/integration tests with `mineunit` in `spec` directory with code coverage analysis using `cluacov`. +Additionally generates badge parameters for coverage badges as well as plain text coverage reports. Example badges: * ![](https://byob.yarr.is/S-S-X/metatool/metatool-coverage) @@ -19,15 +21,15 @@ name: mineunit on: [push, pull_request] jobs: - build: + mineunit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - id: mineunit uses: mt-mods/mineunit-actions@master with: badge-color: "CC9909" - - uses: RubbaBoy/BYOB@v1.2.0 + - uses: RubbaBoy/BYOB@v1.3.0 with: NAME: "${{ steps.mineunit.outputs.badge-name }}" LABEL: "${{ steps.mineunit.outputs.badge-label }}" @@ -38,21 +40,24 @@ jobs: Optional parameters for `mt-mods/mineunit-actions`: -* **`working-directory`** Working directory for unit tests -* **`badge-name`** Code coverage badge name -* **`badge-label`** Code coverage badge label -* **`badge-color`** Code coverage badge color -* **`mineunit-version`** Mineunit version +* **`working-directory`** Working directory for unit tests, can be used when testing modpacks or multiple mods. +* **`badge-name`** Code coverage badge name. +* **`badge-label`** Code coverage badge label. +* **`badge-color`** Code coverage badge color. +* **`mineunit-args`** Mineunit extra arguments, for example to specify `--engine-version 5.7.0`. +* **`mineunit-version`** Mineunit version. Outputs: -* **`steps.mineunit.outputs.badge-name`** Code coverage badge name waiting for issues/#1 -* **`steps.mineunit.outputs.badge-label`** Code coverage badge label waiting for issues/#1 -* **`steps.mineunit.outputs.badge-status`** Code coverage badge status waiting for issues/#1 -* **`steps.mineunit.outputs.badge-color`** Code coverage badge color waiting for issues/#1 -* **`steps.mineunit.outputs.mineunit-stdout`** Stdout produced during busted run -* **`steps.mineunit.outputs.mineunit-spec-missing`** Set to true if no spec files found for busted -* **`steps.mineunit.outputs.mineunit-report`** Mineunit detailed test report -* **`steps.mineunit.outputs.coverage-total`** Total test coverage percentage -* **`steps.mineunit.outputs.coverage-files`** Number of files tested and total number of source files -* **`steps.mineunit.outputs.help-busted-spec-missing`** Help for situation where spec files could not be loaded +* **`steps.mineunit.outputs.badge-name`** Code coverage badge name. +* **`steps.mineunit.outputs.badge-label`** Code coverage badge label. +* **`steps.mineunit.outputs.badge-status`** Code coverage badge status. +* **`steps.mineunit.outputs.badge-color`** Code coverage badge color. +* **`steps.mineunit.outputs.mineunit-stdout`** Stdout produced during mineunit run. +* **`steps.mineunit.outputs.mineunit-spec-missing`** Set to true if no spec files found for busted. +* **`steps.mineunit.outputs.mineunit-report`** Mineunit code coverage summary report. +* **`steps.mineunit.outputs.coverage-total`** Total test coverage percentage. +* **`steps.mineunit.outputs.coverage-files`** Number of files tested and total number of source files. +* **`steps.mineunit.outputs.help-busted-spec-missing`** Help for situation where spec files could not be loaded. + +Based on Docker image https://hub.docker.com/r/mineunit/mineunit diff --git a/action.yml b/action.yml index b6988ae..2788ac9 100644 --- a/action.yml +++ b/action.yml @@ -33,35 +33,26 @@ outputs: # Generated or supplied badge properties badge-name: description: "Code coverage badge name waiting for issues/#1" - value: ${{ steps.badge-wrapper-actions-issue-1.outputs.badge-name }} badge-label: description: "Code coverage badge label waiting for issues/#1" - value: ${{ steps.badge-wrapper-actions-issue-1.outputs.badge-label }} badge-status: description: "Code coverage badge status waiting for issues/#1" - value: "${{ steps.mineunit-coverage.outputs.total }} in ${{ steps.mineunit-coverage.outputs.files }} files" badge-color: description: "Code coverage badge color waiting for issues/#1" - value: ${{ steps.badge-wrapper-actions-issue-1.outputs.badge-color }} # Mineunit test framework output mineunit-stdout: description: "Stdout produced during busted run" - value: ${{ steps.mineunit-tests.outputs.stdout }} mineunit-spec-missing: description: "Set to true if no spec files found for busted" - value: ${{ steps.mineunit-tests.outputs.spec-missing }} mineunit-report: description: "Mineunit detailed test report" - value: ${{ steps.mineunit-report.outputs.report }} coverage-total: description: "Total test coverage percentage" - value: ${{ steps.mineunit-coverage.outputs.total }} coverage-files: description: "Number of files tested and total number of source files" - value: ${{ steps.mineunit-coverage.outputs.files }} # Help content / on demand documentation help-busted-spec-missing: @@ -79,49 +70,5 @@ outputs: ``` runs: - using: composite - steps: - - name: install mineunit - shell: bash - run: | - sudo apt-get install -y luarocks > /dev/null - luarocks install --server=https://luarocks.org/dev --local mineunit ${{ inputs.mineunit-version }} - - id: mineunit-tests - name: mineunit runner - working-directory: "${{ inputs.working-directory }}" - shell: bash - run: | - set +eo pipefail - exec 3>&1 - OUT="$($HOME/.luarocks/bin/mineunit -c ${{ inputs.mineunit-args }} | tee >(cat - >&3); exit ${PIPESTATUS[0]})" - ERR=$? - exec 3>&- - grep_eronly=(grep '0 successes / 0 failures / [1-9] error.\? / 0 pending') - grep_nospec=(grep 'No test files found') - ("${grep_eronly[@]}"<<<"$OUT" && "${grep_nospec[@]}"<<<"$OUT")&>/dev/null && echo "spec-missing=true" >> $GITHUB_OUTPUT - OUT="$(sed 's/\x1B\[[0-9;]\{1,\}[A-Za-z]//g'<<<"$OUT")" - printf 'stdout<> $GITHUB_OUTPUT - exit $ERR - - id: mineunit-report - name: mineunit coverage report - working-directory: "${{ inputs.working-directory }}" - shell: bash - run: | - $HOME/.luarocks/bin/mineunit -r - OUT="$(awk -v p=0 '/^----/{p++;next}p==2{exit}p' luacov.report.out | sort -hrk4)" - printf 'report<> $GITHUB_OUTPUT - - id: mineunit-coverage - name: collect coverage data - working-directory: "${{ inputs.working-directory }}" - shell: bash - run: | - echo "total=$(tail -n 2 luacov.report.out | grep ^Total | grep -o '[0-9.]\+%$')" >> $GITHUB_OUTPUT - awk -v p=0 '/^----/{p++;next}p==2{exit}p' luacov.report.out | sort -hrk4 > luacov.report.sum - echo "files=$(grep -cv '\s0\.00%' luacov.report.sum)/$(wc -l> $GITHUB_OUTPUT - - id: badge-wrapper-actions-issue-1 - name: Input wrapper while waiting for actions in actions feature - shell: bash - run: | - echo "badge-name=${{ inputs.badge-name }}" >> $GITHUB_OUTPUT - echo "badge-label=${{ inputs.badge-label }}" >> $GITHUB_OUTPUT - echo "badge-color=${{ inputs.badge-color }}" >> $GITHUB_OUTPUT + using: docker + image: Dockerfile diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh new file mode 100644 index 0000000..15e3312 --- /dev/null +++ b/scripts/entrypoint.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -eo pipefail + +while read -r ENV; do export -- "$ENV"; done < <(env | grep -- '-[^=]*=' | sed -r ':ape s/^([^-=]*)-/\1_/;tape') + +cd "${INPUT_WORKING_DIRECTORY}" + +echo "Running tests in $(pwd)" +/scripts/run-tests.sh +ERR=$? + +if (($ERR != 0)); then + exit $ERR +fi + +echo "Generating report in $(pwd)" +/scripts/run-report.sh +ERR=$? + +exit $ERR diff --git a/scripts/run-report.sh b/scripts/run-report.sh new file mode 100644 index 0000000..b0ce1f9 --- /dev/null +++ b/scripts/run-report.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -eo pipefail + +# Generate luacov report and write it to output +mineunit -r +OUT="$(awk -v p=0 '/^----/{p++;next}p==2{exit}p' luacov.report.out | sort -hrk4)" +printf 'mineunit-report<> "${GITHUB_OUTPUT}" + +# Read and sort coverage information from luacov report +COVERAGE_TOTAL="$(tail -n 2 luacov.report.out | grep ^Total | grep -o '[0-9.]\+%$')" +echo "coverage-total=${COVERAGE_TOTAL}" >> "${GITHUB_OUTPUT}" +awk -v p=0 '/^----/{p++;next}p==2{exit}p' luacov.report.out | sort -hrk4 > luacov.report.sum +COVERAGE_FILES="$(grep -cv '\s0\.00%' luacov.report.sum)/$(wc -l> "${GITHUB_OUTPUT}" + +# badge-wrapper-actions-issue-1 +echo "badge-name=${INPUT_BADGE_NAME}" >> "${GITHUB_OUTPUT}" +echo "badge-label=${INPUT_BADGE_LABEL}" >> "${GITHUB_OUTPUT}" +echo "badge-color=${INPUT_BADGE_COLOR}" >> "${GITHUB_OUTPUT}" +echo "badge-status=${COVERAGE_TOTAL} in ${COVERAGE_FILES} files" >> "${GITHUB_OUTPUT}" diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh new file mode 100644 index 0000000..c90563b --- /dev/null +++ b/scripts/run-tests.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set +eo pipefail + +# Run tests, collect output and save return code +exec 3>&1 +OUT="$(mineunit -c ${INPUT_MINEUNIT_ARGS} | tee >(cat - >&3); exit ${PIPESTATUS[0]})" +ERR=$? +exec 3>&- + +# Check for some hard errors +grep_eronly=(grep '0 successes / 0 failures / [1-9] error.\? / 0 pending') +grep_nospec=(grep 'No test files found') +("${grep_eronly[@]}"<<<"$OUT" && "${grep_nospec[@]}"<<<"$OUT")&>/dev/null && echo "mineunit-spec-missing=true" >> "${GITHUB_OUTPUT}" + +# Remove some shell stuff and write output +OUT="$(sed 's/\x1B\[[0-9;]\{1,\}[A-Za-z]//g'<<<"$OUT")" +printf 'mineunit-stdout<> "${GITHUB_OUTPUT}" + +# Return original error code +exit $ERR