diff --git a/.github/workflows/auto-tag.yml b/.github/workflows/auto-tag.yml new file mode 100644 index 0000000..33446ca --- /dev/null +++ b/.github/workflows/auto-tag.yml @@ -0,0 +1,12 @@ +name: Auto-tag +on: + push: + tags: + - '*.*.*' +jobs: + auto-tag: + name: Auto-tag + runs-on: ubuntu-latest + steps: + - name: Auto-tag + uses: silverstripe/gha-auto-tag@main diff --git a/README.md b/README.md index c967bff..028cb16 100644 --- a/README.md +++ b/README.md @@ -1 +1,4 @@ -# gha-run-tests \ No newline at end of file +# GitHub Action - Run tests +Run Silverstripe CI matrix tests + +Only intended to be used within [gha-ci](https://github.com/silverstripe/gha-ci). The inputs all come from the matrix generated as a part of that workflow. diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..52b2898 --- /dev/null +++ b/action.yml @@ -0,0 +1,239 @@ +name: Run tests +description: Run tests for a single matrix entry + +inputs: + phpunit: + type: boolean + default: false + phpunit_suite: + type: string + required: false + default: '' + phpunit_fail_on_warning: + type: boolean + default: false + endtoend: + type: boolean + default: false + endtoend_suite: + type: string + required: false + default: '' + endtoend_config: + type: string + required: false + default: '' + js: + type: boolean + default: false + phpcoverage: + type: boolean + default: false + phplinting: + type: boolean + default: false + +runs: + using: composite + steps: + + - name: Validate inputs + shell: bash + env: + PHPUNIT_SUITE: ${{ inputs.phpunit_suite }} + ENDTOEND_SUITE: ${{ inputs.endtoend_suite }} + ENDTOEND_CONFIG: ${{ inputs.endtoend_config }} + run: | + if ! [[ "$PHPUNIT_SUITE" =~ ^[a-zA-Z0-9_\-]*$ ]]; then + echo "Invalid input for phpunit_suite" + exit 1 + fi + if ! [[ "$ENDTOEND_SUITE" =~ ^[a-zA-Z0-9_\-]*$ ]]; then + echo "Invalid input for endtoend_suite" + exit 1 + fi + if ! [[ "$ENDTOEND_CONFIG" =~ ^[a-zA-Z0-9_\./\-]*$ ]]; then + echo "Invalid input for endtoend_config" + exit 1 + fi + + - name: Run PHPUnit + # input booleans are converted to strings + if: ${{ inputs.phpunit == 'true' }} + shell: bash + env: + PHPUNIT_SUITE: ${{ inputs.phpunit_suite }} + run: | + PHPUNIT_OPTIONS="--verbose --colors=always" + if [[ "$PHPUNIT_SUITE" != "all" ]] && [[ "$PHPUNIT_SUITE" != "" ]]; then + PHPUNIT_OPTIONS="$PHPUNIT_OPTIONS --testsuite "$PHPUNIT_SUITE"" + fi + if [[ "${{ inputs.phpunit_fail_on_warning }}" == "true" ]]; then + PHPUNIT_OPTIONS="$PHPUNIT_OPTIONS --fail-on-warning" + fi + vendor/bin/phpunit $PHPUNIT_OPTIONS + echo "Passed" + + - name: Setup chrome and chromedriver + if: ${{ inputs.endtoend == 'true' }} + shell: bash + run: | + echo "Default versions of google-chrome and chromedriver" + GCVR=$(google-chrome --version) + CDVR=$(chromedriver --version) + echo "$GCVR" + echo "$CDVR" + # Example version number is 101.0.4951.64 + [[ "$GCVR" =~ ([0-9]+\.[0-9]+\.[0-9]+)\.[0-9]+ ]] + GCV="${BASH_REMATCH[1]}" + [[ "$CDVR" =~ ([0-9]+\.[0-9]+\.[0-9]+)\.[0-9]+ ]] + CDV="${BASH_REMATCH[1]}" + # Reinstall if a.b.c versions do not match, though allow a different .d version + if [[ "$GCV" != "$CDV" ]]; then + WGC=$(which google-chrome) + echo "google-chrome and chromedriver versions do not match, reinstalling" + sudo apt remove -y --purge google-chrome-stable + # Note that on ubuntu 20.04 and later, these will be installed via a snap. When trying to install + # chromium (or any other snaps), we get a permission error, but it doesn't seem to cause problem. The error looks like this: + # mkdir: cannot create directory '/run/user/1001': Permission denied + sudo apt install -y chromium-browser chromium-chromedriver + echo "Updated versions of chromium-browser and chromedriver" + sudo ln -s $(which chromium-browser) "$WGC" + google-chrome --version + chromedriver --version + else + echo "Default versions match, continuing" + fi + + - name: Run end-to-end tests + if: ${{ inputs.endtoend == 'true' }} + shell: bash + env: + ENDTOEND_SUITE: ${{ inputs.endtoend_suite }} + ENDTOEND_CONFIG: ${{ inputs.endtoend_config }} + run: | + echo "Running behat" + BEHAT_CONFIG="behat.yml" + if [[ "$ENDTOEND_CONFIG" != "" ]]; then + BEHAT_CONFIG="$ENDTOEND_CONFIG" + fi + if ! [[ -f "$BEHAT_CONFIG" ]]; then + echo "$BEHAT_CONFIG config file missing" + exit 1 + fi + # Remove any sneaky attempts to put __behat* files into pull-requests + if [[ -f __behat.yml ]]; then + rm __behat.yml + fi + if [[ -f __behat.php ]]; then + rm __behat.php + fi + if [[ -f __behat_headless.yml ]]; then + rm __behat_headless.yml + fi + # Copy files from the action to temporary locations to generate the new headless behat config + cp "$BEHAT_CONFIG" __behat.yml + cp ${{ github.action_path }}/behat.php __behat.php + cp ${{ github.action_path }}/behat_headless.yml __behat_headless.yml + php __behat.php + rm __behat.php + rm __behat_headless.yml + # start chromedriver as a background process + nohup sh -c "chromedriver" > /dev/null 2>&1 & + if [[ "$ENDTOEND_SUITE" != "root" ]]; then + vendor/bin/behat --colors --strict --config __behat.yml "$ENDTOEND_SUITE" + else + vendor/bin/behat --colors --strict --config __behat.yml + fi + echo "Passed" + + - name: Run JS tests + if: ${{ inputs.js == 'true' }} + shell: bash + run: | + echo "Running JS tests" + if [[ ! -f package.json ]]; then + echo "package.json missing" + exit 1 + fi + if [[ ! -f .nvmrc ]]; then + echo "Missing .nvmrc" + exit 1 + fi + wget https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh + php -r ' + $hash = "dd4b116a7452fc3bb8c0e410ceac27e19b0ba0f900fe2f91818a95c12e92130fdfb8170fec170b9fb006d316f6386f2b"; + if (hash_file("sha384", "install.sh") === $hash) { + echo "Installer verified"; + } else { + echo "Installer corrupt"; + unlink('install.sh'); + } + echo PHP_EOL; + ' + if [[ ! -f install.sh ]]; then + echo "Cannot install nvm" + exit 1 + fi + . install.sh + rm install.sh + export NVM_DIR="$HOME/.nvm" + # this loads nvm into the current terminal + [[ -s "$NVM_DIR/nvm.sh" ]] && \. "$NVM_DIR/nvm.sh" + nvm install + nvm use + rm -rf client/dist + npm install -g yarn + yarn install --network-concurrency 1 + if [[ -d vendor/silverstripe/admin ]]; then + cd vendor/silverstripe/admin + yarn install --network-concurrency 1 + cd ../../.. + fi + yarn run build + echo "Running git diff" + git diff-files --quiet -w --relative=client + git diff --name-status --relative=client + echo "Running yarn test" + yarn run test + echo "Running yarn lint" + yarn run lint + echo "Passed" + + - name: "Run PHP linting" + if: ${{ inputs.phplinting == 'true' }} + shell: bash + run: | + echo "Running PHPCS" + if ! [[ -f phpcs.xml ]] && ! [[ -f phpcs.xml.dist ]]; then + echo "Missing phpcs.xml or phpcs.xml.dist" + exit 1 + fi + vendor/bin/phpcs + # phpstan is optional + if [[ -f phpstan.neon.dist ]]; then + echo "Running PHPStan" + vendor/bin/phpstan analyse + fi + # cow validation is also done here due to it being a tiny piece of work not meriting its own step + if [[ -f .cow.json ]]; then + echo "Running cow schema validate" + vendor/bin/cow schema:validate + fi + echo "Passed" + + - name: "Run PHP coverage" + if: ${{ inputs.phpcoverage == 'true' }} + shell: bash + run: | + echo "Running codecov" + curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --import + curl -Os https://uploader.codecov.io/latest/codecov-linux + curl -Os https://uploader.codecov.io/latest/codecov-linux.SHA256SUM + curl -Os https://uploader.codecov.io/latest/codecov-linux.SHA256SUM.sig + gpg --verify codecov-linux.SHA256SUM.sig codecov-linux.SHA256SUM + shasum -a 256 -c codecov-linux.SHA256SUM + chmod +x codecov-linux + phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml + ./codecov-linux -f coverage.xml; + echo "coverage.xml generated and uploaded to codecov" diff --git a/behat.php b/behat.php new file mode 100644 index 0000000..540a43c --- /dev/null +++ b/behat.php @@ -0,0 +1,20 @@ +