Require a SimpleSAMLphp this module can actually run on #1781
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: ["**"] | |
| pull_request: | |
| types: [opened, synchronize, reopened, closed] | |
| jobs: | |
| basic-tests: | |
| name: Syntax and unit tests, PHP ${{ matrix.php-versions }}, ${{ matrix.operating-system }} | |
| runs-on: [ubuntu-latest] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| php-versions: ["8.3", "8.4", "8.5"] | |
| steps: | |
| - name: Setup PHP, with composer and extensions | |
| uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php | |
| with: | |
| php-version: ${{ matrix.php-versions }} | |
| extensions: mbstring, xml | |
| tools: composer:v2 | |
| coverage: pcov | |
| - name: Setup problem matchers for PHP | |
| run: echo "::add-matcher::${{ runner.tool_cache }}/php.json" | |
| - name: Setup problem matchers for PHPUnit | |
| run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" | |
| - name: Set git to use LF | |
| run: | | |
| git config --global core.autocrlf false | |
| git config --global core.eol lf | |
| - uses: actions/checkout@v6 | |
| - name: Get composer cache directory | |
| id: composer-cache | |
| run: echo COMPOSER_CACHE="$(composer config cache-files-dir)" >> "$GITHUB_ENV" | |
| - name: Cache composer dependencies | |
| uses: actions/cache@v5 | |
| with: | |
| path: $COMPOSER_CACHE | |
| key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}" | |
| restore-keys: ${{ runner.os }}-composer- | |
| - name: Validate composer.json and composer.lock | |
| run: composer validate | |
| - name: Install Composer dependencies | |
| run: composer install --no-progress --prefer-dist --optimize-autoloader | |
| - name: Decide whether to run code coverage or not | |
| if: ${{ matrix.php-versions != '8.5' }} | |
| run: | | |
| echo "NO_COVERAGE=--no-coverage" >> $GITHUB_ENV | |
| - name: Run unit tests | |
| run: | | |
| echo $NO_COVERAGE | |
| ./vendor/bin/phpunit $NO_COVERAGE | |
| - name: Run integration tests | |
| run: | | |
| echo $NO_COVERAGE | |
| ./vendor/bin/phpunit $NO_COVERAGE --no-configuration -c phpunit.integration.xml | |
| - name: Merge coverage data | |
| if: ${{ matrix.php-versions == '8.5' }} | |
| run: | | |
| ./vendor/bin/phpunit-merger log build/logs/partial_junit/ build/logs/junit.xml | |
| ./vendor/bin/phpunit-merger coverage build/logs/partial_clover/ build/logs/clover.xml | |
| - name: Save coverage data | |
| if: ${{ matrix.php-versions == '8.5' }} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: build-data | |
| path: ${{ github.workspace }}/build | |
| security: | |
| name: Security checks | |
| runs-on: [ubuntu-latest] | |
| steps: | |
| - name: Setup PHP, with composer and extensions | |
| uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php | |
| with: | |
| php-version: "8.3" | |
| extensions: mbstring, xml | |
| tools: composer:v2 | |
| coverage: none | |
| - name: Setup problem matchers for PHP | |
| run: echo "::add-matcher::${{ runner.tool_cache }}/php.json" | |
| - uses: actions/checkout@v6 | |
| - name: Get composer cache directory | |
| id: composer-cache | |
| run: echo COMPOSER_CACHE="$(composer config cache-files-dir)" >> "$GITHUB_ENV" | |
| - name: Cache composer dependencies | |
| uses: actions/cache@v5 | |
| with: | |
| path: $COMPOSER_CACHE | |
| key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}" | |
| restore-keys: ${{ runner.os }}-composer- | |
| - name: Install Composer dependencies | |
| run: composer install --no-progress --prefer-dist --optimize-autoloader | |
| - name: Security check for locked dependencies | |
| uses: symfonycorp/security-checker-action@v5 | |
| - name: Update Composer dependencies | |
| run: composer update --no-progress --prefer-dist --optimize-autoloader | |
| - name: Security check for updated dependencies | |
| uses: symfonycorp/security-checker-action@v5 | |
| sanity-check: | |
| name: Sanity checks | |
| runs-on: [ubuntu-latest] | |
| steps: | |
| - name: Setup PHP, with composer and extensions | |
| uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php | |
| with: | |
| php-version: "8.3" | |
| extensions: mbstring, xml | |
| tools: composer:v2 | |
| coverage: none | |
| - name: Setup problem matchers for PHP | |
| run: echo "::add-matcher::${{ runner.tool_cache }}/php.json" | |
| - uses: actions/checkout@v6 | |
| - name: Get composer cache directory | |
| id: composer-cache | |
| run: echo COMPOSER_CACHE="$(composer config cache-files-dir)" >> "$GITHUB_ENV" | |
| - name: Cache composer dependencies | |
| uses: actions/cache@v5 | |
| with: | |
| path: $COMPOSER_CACHE | |
| key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}" | |
| restore-keys: ${{ runner.os }}-composer- | |
| - name: Install Composer dependencies | |
| run: composer install --no-progress --prefer-dist --optimize-autoloader | |
| quality: | |
| name: Quality control | |
| runs-on: [ubuntu-latest] | |
| needs: [basic-tests] | |
| steps: | |
| - name: Setup PHP, with composer and extensions | |
| uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php | |
| with: | |
| php-version: "8.5" | |
| tools: composer:v2 | |
| extensions: mbstring, xml | |
| - name: Setup problem matchers for PHP | |
| run: echo "::add-matcher::${{ runner.tool_cache }}/php.json" | |
| - uses: actions/checkout@v6 | |
| - name: Get composer cache directory | |
| id: composer-cache | |
| run: echo COMPOSER_CACHE="$(composer config cache-files-dir)" >> "$GITHUB_ENV" | |
| - name: Cache composer dependencies | |
| uses: actions/cache@v5 | |
| with: | |
| path: $COMPOSER_CACHE | |
| key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}" | |
| restore-keys: ${{ runner.os }}-composer- | |
| - name: Install Composer dependencies | |
| run: composer install --no-progress --prefer-dist --optimize-autoloader | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: build-data | |
| path: ${{ github.workspace }}/build | |
| - name: Codecov | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| fail_ci_if_error: true | |
| verbose: true | |
| - name: PHP Code Sniffer | |
| if: always() | |
| run: php vendor/bin/phpcs | |
| - name: Psalm | |
| if: always() | |
| run: php vendor/bin/psalm --show-info=true | |
| conformance-suite: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # SimpleSAMLphp ref to build the OP base image from. Any Composer version works: a released tag | |
| # (e.g. "v2.5.3.1") or a branch (e.g. "dev-simplesamlphp-2.5"). Keep this on a released tag which | |
| # satisfies the simplesamlphp/simplesamlphp requirement in composer.json, so that conformance | |
| # runs against a SimpleSAMLphp a deployment can actually install. Keep it usable as a Docker tag | |
| # as well: the base image is addressed as ssp-base:<this value> below, while the build script | |
| # replaces anything a tag may not hold, so a ref with a '/' in it would not be found here. | |
| ssp-composer-version: ["v2.5.3.1"] | |
| env: | |
| SUITE_BASE_URL: https://localhost.emobix.co.uk:8443 | |
| VERSION: release-v5.1.45 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| path: main | |
| - name: Setup Python Dependencies | |
| run: | | |
| pip install --upgrade pip | |
| pip install httpx | |
| - name: Conformance Suite Checkout | |
| if: ${{ steps.cache.outputs.cache-hit != 'true' }} | |
| run: git clone --depth 1 --single-branch --branch $VERSION https://gitlab.com/openid/conformance-suite.git | |
| - name: Conformance Suite Build | |
| working-directory: ./conformance-suite | |
| if: ${{ steps.cache.outputs.cache-hit != 'true' }} | |
| env: | |
| MAVEN_CACHE: ./m2 | |
| run: | | |
| sed -i -e 's/localhost/localhost.emobix.co.uk/g' src/main/resources/application.properties | |
| sed -i -e 's/-B clean/-B -DskipTests=true/g' builder-compose.yml | |
| python3 -c "import pathlib; p = pathlib.Path('src/main/java/net/openid/conformance/frontchannel/BrowserControl.java'); p.write_text(p.read_text().replace('((JavascriptExecutor) webDriver).executeScript(\"return document.readyState\").equals(\"complete\")', '\"complete\".equals(((JavascriptExecutor) webDriver).executeScript(\"return document.readyState\"))'))" | |
| docker compose -f builder-compose.yml run builder | |
| - name: Run Conformance Suite | |
| working-directory: ./conformance-suite | |
| run: | | |
| docker compose -f docker-compose-dev.yml up -d | |
| while ! curl -skfail https://localhost.emobix.co.uk:8443/api/runner/available >/dev/null; do sleep 2; done | |
| - name: Build SimpleSAMLphp base image | |
| working-directory: ./main | |
| # SimpleSAMLphp is installed into the base image via Composer (cirrus's SSP_COMPOSER_VERSION | |
| # path), so any tag or branch can be used. The image is built locally each run and not pushed | |
| # to any registry. Same script a developer runs locally, so the two cannot drift apart. | |
| run: ./docker/build-ssp-base.sh ${{ matrix.ssp-composer-version }} | |
| - name: Generate development certificates | |
| working-directory: ./main | |
| # The TLS certificate nginx-proxy serves the OP with, and the OIDC module | |
| # signing key pair, are generated per run instead of being kept in Git. | |
| run: ./docker/generate-dev-certs.sh | |
| - name: Start SSP docker | |
| working-directory: ./main | |
| # Must run after conformance suite since they share a docker network. | |
| run: | | |
| SSP_IMAGE=ssp-base:${{ matrix.ssp-composer-version }} OIDC_VERSION=@dev docker compose -f docker/docker-compose.yml --project-directory . up -d --build | |
| sleep 30 | |
| # while ! curl -skfail https://op.local.stack-dev.cirrusidentity.com/.well-known/openid-configuration >/dev/null; do sleep 2; done | |
| - name: Run Basic conformance tests | |
| run: | | |
| ./conformance-suite/scripts/run-test-plan.py --expected-failures-file ./main/conformance-tests/basic-warnings.json --expected-skips-file ./main/conformance-tests/basic-skips.json "oidcc-basic-certification-test-plan[server_metadata=discovery][client_registration=static_client]" ./main/conformance-tests/conformance-basic-ci.json | |
| - name: Run Implicit conformance tests | |
| run: | | |
| ./conformance-suite/scripts/run-test-plan.py --expected-failures-file ./main/conformance-tests/implicit-warnings.json --expected-skips-file ./main/conformance-tests/implicit-skips.json "oidcc-implicit-certification-test-plan[server_metadata=discovery][client_registration=static_client]" ./main/conformance-tests/conformance-implicit-ci.json | |
| - name: Run RP logout | |
| run: | | |
| ./conformance-suite/scripts/run-test-plan.py "oidcc-rp-initiated-logout-certification-test-plan[response_type=code][client_registration=static_client]" ./main/conformance-tests/conformance-rp-initiated-logout-ci.json | |
| - name: Run RP backchannel | |
| run: | | |
| ./conformance-suite/scripts/run-test-plan.py "oidcc-backchannel-rp-initiated-logout-certification-test-plan[response_type=code][client_registration=static_client]" ./main/conformance-tests/conformance-back-channel-logout-ci.json | |
| - name: Run form_post basic tests | |
| run: | | |
| ./conformance-suite/scripts/run-test-plan.py "oidcc-formpost-basic-certification-test-plan[server_metadata=discovery][client_registration=static_client]" ./main/conformance-tests/conformance-basic-ci.json | |
| - name: Run form_post implicit tests | |
| run: | | |
| ./conformance-suite/scripts/run-test-plan.py "oidcc-formpost-implicit-certification-test-plan[server_metadata=discovery][client_registration=static_client]" ./main/conformance-tests/conformance-implicit-ci.json | |
| - name: Run Dynamic registration conformance tests | |
| # The only remaining non-passing tests are two OP-wide gaps (signed UserInfo | |
| # and signing-key rotation), which are recorded as expected failures in | |
| # conformance-tests/dynamic-warnings.json, so this step is a blocking gate. | |
| # See docs/5-oidc-conformance.md for the inventory. | |
| run: | | |
| ./conformance-suite/scripts/run-test-plan.py --expected-failures-file ./main/conformance-tests/dynamic-warnings.json --expected-skips-file ./main/conformance-tests/dynamic-skips.json "oidcc-dynamic-certification-test-plan[response_type=code]" ./main/conformance-tests/conformance-dynamic-ci.json | |
| - name: Dump OP logs | |
| if: failure() | |
| working-directory: ./main | |
| # What the suite reports is only its own side of the exchange, and some failures say nothing there: | |
| # a request the OP never sent reads as a test waiting for a callback until it times out, with no | |
| # failed check anywhere. The reason is in the OP's log, which otherwise leaves with the container. | |
| # Same compose invocation as "Start SSP docker", so this addresses the project that step created. | |
| run: | | |
| docker compose -f docker/docker-compose.yml --project-directory . logs --no-color --tail 2000 oidc-op || true | |
| - name: Stop SSP | |
| working-directory: ./main | |
| run: | | |
| docker compose -f docker/docker-compose.yml down | |
| - name: Stop Conformance Suite | |
| working-directory: ./conformance-suite | |
| # cleaning up errors out on removing the network, so add "|| true" to prevent that from breaking the build | |
| run: | | |
| docker compose -f docker-compose-dev.yml down || true | |
| sudo rm -rf mongo | |