Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions .github/workflows/smoke-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,126 @@ jobs:
split-total: 5
split-index: 1
- run: echo "The output test suite is ${{ steps.split-tests.outputs.test-suite }}"

smoke-test-working-directory:
runs-on: ubuntu-latest
name: Smoke Test Working Directory
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v7
with:
repository: eliotsykes/rspec-rails-examples
path: examples/
- uses: ./
id: relative
name: Relative working-directory
with:
working-directory: examples
glob: spec/**/*_spec.rb
split-total: 1
split-index: 0
- uses: ./
id: absolute
name: Absolute working-directory
with:
working-directory: ${{ github.workspace }}/examples
glob: spec/**/*_spec.rb
split-total: 1
split-index: 0
- name: Assert output is relative to working-directory and covers the glob
env:
RELATIVE: ${{ steps.relative.outputs.test-suite }}
ABSOLUTE: ${{ steps.absolute.outputs.test-suite }}
run: |
set -euo pipefail

echo "$RELATIVE" | tr ' ' '\n' | sed '/^$/d' | sort -u > /tmp/relative.txt
echo "$ABSOLUTE" | tr ' ' '\n' | sed '/^$/d' | sort -u > /tmp/absolute.txt
(cd examples && find spec -name '*_spec.rb' | sort -u) > /tmp/expected.txt

if [ ! -s /tmp/expected.txt ]; then
echo "::error::Fixture has no spec files, the test is not testing anything"
exit 1
fi

if ! diff -u /tmp/expected.txt /tmp/relative.txt; then
echo "::error::Relative working-directory output does not match the files under examples/spec"
exit 1
fi

if ! diff -u /tmp/relative.txt /tmp/absolute.txt; then
echo "::error::Absolute and relative working-directory outputs differ"
exit 1
fi

if grep -q '^examples/' /tmp/relative.txt; then
echo "::error::Output paths should be relative to working-directory, not the workspace"
exit 1
fi

echo "OK: $(wc -l < /tmp/expected.txt) files, paths relative to working-directory"

smoke-test-expected-failures:
runs-on: ubuntu-latest
name: Smoke Test Expected Failures
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v7
with:
repository: eliotsykes/rspec-rails-examples
path: examples/
- uses: ./
id: missing-working-directory
name: Nonexistent working-directory
continue-on-error: true
with:
working-directory: examples/does-not-exist
glob: spec/**/*_spec.rb
split-total: 2
split-index: 0
- uses: ./
id: index-out-of-range
name: split-index equal to split-total
continue-on-error: true
with:
glob: examples/spec/**/*_spec.rb
split-total: 2
split-index: 2
- uses: ./
id: zero-total
name: split-total of zero
continue-on-error: true
with:
glob: examples/spec/**/*_spec.rb
split-total: 0
split-index: 0
- uses: ./
id: control
name: Control, valid inputs must still pass
continue-on-error: true
with:
glob: examples/spec/**/*_spec.rb
split-total: 2
split-index: 1
- name: Assert each invalid input failed and the control passed
env:
MISSING_WORKING_DIRECTORY: ${{ steps.missing-working-directory.outcome }}
INDEX_OUT_OF_RANGE: ${{ steps.index-out-of-range.outcome }}
ZERO_TOTAL: ${{ steps.zero-total.outcome }}
CONTROL: ${{ steps.control.outcome }}
run: |
set -euo pipefail
status=0
expect() {
if [ "$2" != "$3" ]; then
echo "::error::$1: expected outcome '$3' but got '$2'"
status=1
else
echo "OK: $1 -> $2"
fi
}
expect "nonexistent working-directory" "$MISSING_WORKING_DIRECTORY" failure
expect "split-index equal to split-total" "$INDEX_OUT_OF_RANGE" failure
expect "split-total of zero" "$ZERO_TOTAL" failure
expect "valid inputs (control)" "$CONTROL" success
exit "$status"
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Timings must be per test **file**. If your runner writes one report per worker,
| `exclude-glob` | Glob pattern to exclude test files | `string` | | `""` |
| `junit-path` | Path to a JUnit XML report to use for test timings | `string` | | `""` |
| `line-count` | Use line count to estimate test duration | `bool` | | `false` |
| `working-directory` | Directory to run in, relative to `$GITHUB_WORKSPACE` (or absolute). `glob`, `exclude-glob` and `junit-path` are resolved relative to it, and `test-suite` paths are relative to it. Useful for monorepos | `string` | | `""` (the workspace) |

### Outputs

Expand Down
22 changes: 21 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ inputs:
line-count:
description: Use line count to estimate test times (boolean)
required: false
working-directory:
description: Directory to run in, relative to GITHUB_WORKSPACE (or absolute). The glob, exclude-glob and junit-path inputs are resolved relative to it, and the output paths are relative to it. Defaults to GITHUB_WORKSPACE.
required: false
default: ""
outputs:
test-suite:
description: "A subset of tests, based on the the split index and split type"
Expand All @@ -46,6 +50,9 @@ runs:
SPLIT_TESTS_SHA256: 6988628a956f065c9eced4bb77bcc0b5c111717c1d4748b701c03afabb8349dd
run: |
set -euo pipefail
# Install into GITHUB_WORKSPACE so the binary can be found by absolute
# path regardless of the working-directory input.
cd "$GITHUB_WORKSPACE"
curl -fL "https://github.com/leonid-shevtsov/split_tests/releases/download/${SPLIT_TESTS_VERSION}/split_tests.linux.gz" -o split_tests.gz
if ! echo "${SPLIT_TESTS_SHA256} split_tests.gz" | sha256sum -c -; then
echo "::error::split_tests ${SPLIT_TESTS_VERSION} checksum mismatch. Actual sha256: $(sha256sum split_tests.gz | cut -d' ' -f1)" >&2
Expand All @@ -63,9 +70,12 @@ runs:
EXCLUDE_GLOB_INPUT: ${{ inputs.exclude-glob }}
JUNIT_PATH: ${{ inputs.junit-path }}
LINE_COUNT: ${{ inputs.line-count }}
WORKING_DIRECTORY: ${{ inputs.working-directory }}
run: |
set -euo pipefail

SPLIT_TESTS_BIN="$GITHUB_WORKSPACE/split_tests"

# setup split type
if [ -n "$JUNIT_PATH" ]; then
echo "junit-path set. Splitting based on JUnit timings"
Expand All @@ -83,7 +93,17 @@ runs:
EXCLUDE_GLOB=(-exclude-glob="$EXCLUDE_GLOB_INPUT")
fi

TESTS=$(./split_tests "${SPLIT_BY[@]}" -split-index="$SPLIT_INDEX" -split-total="$SPLIT_TOTAL" -glob="$GLOB" "${EXCLUDE_GLOB[@]}")
# Resolve relative paths from the workspace, then run from there.
cd "$GITHUB_WORKSPACE"
if [ -n "$WORKING_DIRECTORY" ]; then
if [ ! -d "$WORKING_DIRECTORY" ]; then
echo "::error::working-directory '$WORKING_DIRECTORY' does not exist"
exit 1
fi
cd "$WORKING_DIRECTORY"
fi

TESTS=$("$SPLIT_TESTS_BIN" "${SPLIT_BY[@]}" -split-index="$SPLIT_INDEX" -split-total="$SPLIT_TOTAL" -glob="$GLOB" "${EXCLUDE_GLOB[@]}")

echo "$TESTS"

Expand Down
Loading