Move leading app to SDM plugin & workflow files update to read these apps from SDM plugin #188
Workflow file for this run
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: Multi Tenancy Deploy & Integration Testπ | |
| on: | |
| pull_request: | |
| types: [closed] | |
| branches: | |
| - develop | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| packages: read # Added permission to read packages | |
| jobs: | |
| deploy: | |
| environment: dev | |
| if: github.event.pull_request.merged == true | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Wait for 5 minutes β³ | |
| run: | | |
| sleep 300 | |
| echo "β³ Waiting for snapshot deployment... Initiating deployment in 5 minutes." | |
| - name: Checkout this repository π | |
| uses: actions/checkout@v6 | |
| - name: Set up JDK 21 β | |
| uses: actions/setup-java@v3 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '21' | |
| - name: Build and package π¦ | |
| run: | | |
| echo "π¨ Building and packaging..." | |
| mvn clean install -P unit-tests -DskipIntegrationTests | |
| echo "β Build completed successfully!" | |
| - name: Setup Node.js π’ | |
| uses: actions/setup-node@v3 | |
| with: | |
| node-version: '20' # Ensure to use at least version 18 | |
| - name: Install MBT βοΈ | |
| run: | | |
| echo "π§ Installing MBT..." | |
| npm install -g mbt | |
| echo "β MBT installation complete!" | |
| - name: Change directory to cloud-cap-samples-java π | |
| working-directory: app/multi-tenant/central-space/cloud-cap-samples-java | |
| run: | | |
| pwd | |
| echo "βοΈ Directory changed!" | |
| - name: Set REPOSITORY_ID π | |
| id: set_repository_id | |
| run: | | |
| echo "repository_id=${{ secrets.REPOSITORY_ID }}" >> $GITHUB_OUTPUT | |
| - name: Run mbt build π¨ | |
| working-directory: app/multi-tenant/central-space/cloud-cap-samples-java | |
| run: | | |
| echo "π Running MBT build..." | |
| echo "java version:" | |
| java --version | |
| sed -i 's|__REPOSITORY_ID__|${{ steps.set_repository_id.outputs.repository_id }}|g' mta.yaml | |
| mbt build | |
| echo "β MBT build completed!" | |
| - name: Deploy to Cloud Foundry βοΈ | |
| working-directory: app/multi-tenant/central-space/cloud-cap-samples-java | |
| env: | |
| CF_API: ${{ secrets.CF_API }} | |
| CF_USER: ${{ secrets.CF_USER }} | |
| CF_PASSWORD: ${{ secrets.CF_PASSWORD }} | |
| CF_ORG: ${{ secrets.CF_ORG }} | |
| CF_SPACE: ${{ secrets.CF_SPACE }} | |
| run: | | |
| set +x | |
| echo "::add-mask::$CF_API" | |
| echo "::add-mask::$CF_USER" | |
| echo "::add-mask::$CF_PASSWORD" | |
| echo "::add-mask::$CF_ORG" | |
| echo "::add-mask::$CF_SPACE" | |
| echo "π Deploying..." | |
| echo "π§ Installing Cloud Foundry CLI and plugins..." | |
| # Install cf CLI plugin | |
| wget -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo tee /etc/apt/trusted.gpg.d/cloudfoundry.asc | |
| echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list | |
| sudo apt update | |
| sudo apt install cf8-cli | |
| cf install-plugin multiapps -f | |
| echo "β Cloud Foundry CLI setup complete!" | |
| # Login to Cloud Foundry again to ensure session is active | |
| echo "π Logging in to Cloud Foundry..." | |
| cf login -a "$CF_API" -u "$CF_USER" -p "$CF_PASSWORD" -o "$CF_ORG" -s "$CF_SPACE" > /dev/null | |
| echo "β Logged in successfully!" | |
| # Deploy the application | |
| echo "π Current directory.." | |
| pwd | |
| ls -lrth | |
| echo "βΆοΈ Running cf deploy..." | |
| cf deploy mta_archives/bookshop-mt_1.0.0.mtar -f | |
| echo "β Deployment complete!" | |
| integration-test: | |
| environment: dev | |
| needs: deploy | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| tokenFlow: [namedUser, technicalUser] | |
| tenant: [TENANT1, TENANT2] | |
| testClass: | |
| - IntegrationTest_SingleFacet | |
| - IntegrationTest_MultipleFacet | |
| - IntegrationTest_Chapters_MultipleFacet | |
| steps: | |
| - name: Checkout repository β | |
| uses: actions/checkout@v6 | |
| - name: Set up Java 21 β | |
| uses: actions/setup-java@v3 | |
| with: | |
| java-version: 21 | |
| distribution: 'temurin' | |
| cache: 'maven' | |
| - name: Cache CF CLI π¦ | |
| id: cache-cf-cli | |
| uses: actions/cache@v4 | |
| with: | |
| path: /usr/bin/cf8 | |
| key: cf-cli-v8-${{ runner.os }} | |
| - name: Install Cloud Foundry CLI and jq π¦ | |
| if: steps.cache-cf-cli.outputs.cache-hit != 'true' | |
| run: | | |
| echo "π§ Installing Cloud Foundry CLI..." | |
| wget -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add - | |
| echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list | |
| sudo apt-get update | |
| sudo apt-get install cf8-cli | |
| - name: Install jq π¦ | |
| run: | | |
| if ! command -v jq &> /dev/null; then | |
| sudo apt-get update && sudo apt-get install -y jq | |
| fi | |
| - name: Determine Cloud Foundry Space π | |
| id: determine_space | |
| env: | |
| CF_SPACE: ${{ secrets.CF_SPACE }} | |
| run: | | |
| if [ "${{ github.event.inputs.cf_space }}" == "developcap" ]; then | |
| space="$CF_SPACE" | |
| else | |
| space="${{ github.event.inputs.cf_space }}" | |
| fi | |
| echo "π Space determined: $space" | |
| echo "space=$space" >> $GITHUB_OUTPUT | |
| - name: Login to Cloud Foundry π | |
| env: | |
| CF_API: ${{ secrets.CF_API }} | |
| CF_USER: ${{ secrets.CF_USER }} | |
| CF_PASSWORD: ${{ secrets.CF_PASSWORD }} | |
| CF_ORG: ${{ secrets.CF_ORG }} | |
| CF_SPACE: ${{ secrets.CF_SPACE }} | |
| run: | | |
| set +x | |
| echo "::add-mask::$CF_API" | |
| echo "::add-mask::$CF_USER" | |
| echo "::add-mask::$CF_PASSWORD" | |
| echo "::add-mask::$CF_ORG" | |
| echo "::add-mask::$CF_SPACE" | |
| echo "π Logging in to Cloud Foundry..." | |
| cf login -a "$CF_API" \ | |
| -u "$CF_USER" \ | |
| -p "$CF_PASSWORD" \ | |
| -o "$CF_ORG" \ | |
| -s "$CF_SPACE" > /dev/null | |
| - name: Fetch and Escape Client Details for single tenant π | |
| id: fetch_credentials | |
| run: | | |
| echo "Fetching client details for single tenant..." | |
| service_instance_guid=$(cf service demoappjava-public-uaa --guid) | |
| if [ -z "$service_instance_guid" ]; then | |
| echo "β Error: Unable to retrieve service instance GUID"; exit 1; | |
| fi | |
| bindings_response=$(cf curl "/v3/service_credential_bindings?service_instance_guids=${service_instance_guid}") | |
| binding_guid=$(echo "$bindings_response" | jq -r '.resources[0].guid') | |
| if [ -z "$binding_guid" ]; then | |
| echo "β Error: Unable to retrieve binding GUID"; exit 1; | |
| fi | |
| binding_details=$(cf curl "/v3/service_credential_bindings/${binding_guid}/details") | |
| clientSecret=$(echo "$binding_details" | jq -r '.credentials.clientsecret') | |
| if [ -z "$clientSecret" ] || [ "$clientSecret" == "null" ]; then | |
| echo "β Error: clientSecret is not set or is null"; exit 1; | |
| fi | |
| escapedClientSecret=$(echo "$clientSecret" | sed 's/\$/\\$/g') | |
| echo "::add-mask::$escapedClientSecret" | |
| clientID=$(echo "$binding_details" | jq -r '.credentials.clientid') | |
| if [ -z "$clientID" ] || [ "$clientID" == "null" ]; then | |
| echo "β Error: clientID is not set or is null"; exit 1; | |
| fi | |
| echo "::add-mask::$clientID" | |
| echo "CLIENT_SECRET=$escapedClientSecret" >> $GITHUB_OUTPUT | |
| echo "CLIENT_ID=$clientID" >> $GITHUB_OUTPUT | |
| echo "β Client details fetched successfully!" | |
| - name: Fetch and Escape Client Details for multi tenant π | |
| id: fetch_credentials_mt | |
| run: | | |
| echo "Fetching client details for multi tenant..." | |
| service_instance_guid=$(cf service bookshop-mt-uaa --guid) | |
| if [ -z "$service_instance_guid" ]; then | |
| echo "β Error: Unable to retrieve service instance GUID"; exit 1; | |
| fi | |
| bindings_response=$(cf curl "/v3/service_credential_bindings?service_instance_guids=${service_instance_guid}") | |
| binding_guid=$(echo "$bindings_response" | jq -r '.resources[0].guid') | |
| if [ -z "$binding_guid" ]; then | |
| echo "β Error: Unable to retrieve binding GUID"; exit 1; | |
| fi | |
| binding_details=$(cf curl "/v3/service_credential_bindings/${binding_guid}/details") | |
| clientSecret_mt=$(echo "$binding_details" | jq -r '.credentials.clientsecret') | |
| if [ -z "$clientSecret_mt" ] || [ "$clientSecret_mt" == "null" ]; then | |
| echo "β Error: clientSecret_mt is not set or is null"; exit 1; | |
| fi | |
| escapedClientSecret_mt=$(echo "$clientSecret_mt" | sed 's/\$/\\$/g') | |
| echo "::add-mask::$escapedClientSecret_mt" | |
| clientID_mt=$(echo "$binding_details" | jq -r '.credentials.clientid') | |
| if [ -z "$clientID_mt" ] || [ "$clientID_mt" == "null" ]; then | |
| echo "β Error: clientID_mt is not set or is null"; exit 1; | |
| fi | |
| echo "::add-mask::$clientID_mt" | |
| echo "CLIENT_SECRET_MT=$escapedClientSecret_mt" >> $GITHUB_OUTPUT | |
| echo "CLIENT_ID_MT=$clientID_mt" >> $GITHUB_OUTPUT | |
| echo "β Multi-tenant client details fetched successfully!" | |
| - name: Prepare credentials file π | |
| env: | |
| CLIENT_SECRET: ${{ steps.fetch_credentials.outputs.CLIENT_SECRET }} | |
| CLIENT_ID: ${{ steps.fetch_credentials.outputs.CLIENT_ID }} | |
| CLIENT_SECRET_MT: ${{ steps.fetch_credentials_mt.outputs.CLIENT_SECRET_MT }} | |
| CLIENT_ID_MT: ${{ steps.fetch_credentials_mt.outputs.CLIENT_ID_MT }} | |
| CF_ORG: ${{ secrets.CF_ORG }} | |
| CF_SPACE: ${{ secrets.CF_SPACE }} | |
| CAPAUTH_URL: ${{ secrets.CAPAUTH_URL }} | |
| AUTHURLMT1: ${{ secrets.AUTHURLMT1 }} | |
| AUTHURLMT2: ${{ secrets.AUTHURLMT2 }} | |
| CF_USER: ${{ secrets.CF_USER }} | |
| CF_PASSWORD: ${{ secrets.CF_PASSWORD }} | |
| NOSDMROLEUSERNAME: ${{ secrets.NOSDMROLEUSERNAME }} | |
| NOSDMROLEUSERPASSWORD: ${{ secrets.NOSDMROLEUSERPASSWORD }} | |
| run: | | |
| echo "π Preparing credentials for ${{ matrix.tokenFlow }} - ${{ matrix.tenant }}..." | |
| set +x | |
| set -e | |
| PROPERTIES_FILE="sdm/src/test/resources/credentials.properties" | |
| appUrl="$CF_ORG-$CF_SPACE-demoappjava-srv.cfapps.eu12.hana.ondemand.com" | |
| appUrlMT="$CF_ORG-$CF_SPACE-bookshop-mt-srv.cfapps.eu12.hana.ondemand.com" | |
| authUrl="$CAPAUTH_URL" | |
| authUrlMT1="$AUTHURLMT1" | |
| authUrlMT2="$AUTHURLMT2" | |
| clientID="$CLIENT_ID" | |
| clientSecret="$CLIENT_SECRET" | |
| clientIDMT="$CLIENT_ID_MT" | |
| clientSecretMT="$CLIENT_SECRET_MT" | |
| username="$CF_USER" | |
| password="$CF_PASSWORD" | |
| noSDMRoleUsername="$NOSDMROLEUSERNAME" | |
| noSDMRoleUserPassword="$NOSDMROLEUSERPASSWORD" | |
| echo "::add-mask::$clientSecret" | |
| echo "::add-mask::$clientID" | |
| echo "::add-mask::$clientSecretMT" | |
| echo "::add-mask::$clientIDMT" | |
| echo "::add-mask::$username" | |
| echo "::add-mask::$password" | |
| echo "::add-mask::$noSDMRoleUsername" | |
| echo "::add-mask::$noSDMRoleUserPassword" | |
| if [ -z "$appUrl" ]; then echo "β Error: appUrl is not set"; exit 1; fi | |
| if [ -z "$appUrlMT" ]; then echo "β Error: appUrlMT is not set"; exit 1; fi | |
| if [ -z "$authUrl" ]; then echo "β Error: authUrl is not set"; exit 1; fi | |
| if [ -z "$authUrlMT1" ]; then echo "β Error: authUrlMT1 is not set"; exit 1; fi | |
| if [ -z "$authUrlMT2" ]; then echo "β Error: authUrlMT2 is not set"; exit 1; fi | |
| if [ -z "$clientID" ]; then echo "β Error: clientID is not set"; exit 1; fi | |
| if [ -z "$clientSecret" ]; then echo "β Error: clientSecret is not set"; exit 1; fi | |
| if [ -z "$clientIDMT" ]; then echo "β Error: clientIDMT is not set"; exit 1; fi | |
| if [ -z "$clientSecretMT" ]; then echo "β Error: clientSecretMT is not set"; exit 1; fi | |
| if [ -z "$username" ]; then echo "β Error: username is not set"; exit 1; fi | |
| if [ -z "$password" ]; then echo "β Error: password is not set"; exit 1; fi | |
| if [ -z "$noSDMRoleUsername" ]; then echo "β Error: noSDMRoleUsername is not set"; exit 1; fi | |
| if [ -z "$noSDMRoleUserPassword" ]; then echo "β Error: noSDMRoleUserPassword is not set"; exit 1; fi | |
| cat > "$PROPERTIES_FILE" <<EOL | |
| appUrl=$appUrl | |
| appUrlMT=$appUrlMT | |
| authUrl=$authUrl | |
| authUrlMT1=$authUrlMT1 | |
| authUrlMT2=$authUrlMT2 | |
| clientID=$clientID | |
| clientSecret=$clientSecret | |
| clientIDMT=$clientIDMT | |
| clientSecretMT=$clientSecretMT | |
| username=$username | |
| password=$password | |
| noSDMRoleUsername=$noSDMRoleUsername | |
| noSDMRoleUserPassword=$noSDMRoleUserPassword | |
| EOL | |
| echo "β Credentials file prepared!" | |
| - name: Run integration tests (${{ matrix.testClass }} - ${{ matrix.tokenFlow }} - ${{ matrix.tenant }}) π― | |
| run: | | |
| echo "π― Running Maven integration tests: testClass=${{ matrix.testClass }}, tokenFlow=${{ matrix.tokenFlow }}, tenant=${{ matrix.tenant }}" | |
| MAX_RETRIES=3 | |
| ATTEMPT=0 | |
| EXIT_CODE=1 | |
| while [ $ATTEMPT -lt $MAX_RETRIES ]; do | |
| ATTEMPT=$((ATTEMPT + 1)) | |
| echo "π Attempt $ATTEMPT of $MAX_RETRIES..." | |
| if mvn clean verify -P integration-tests -DtokenFlow=${{ matrix.tokenFlow }} -DtenancyModel=multi -Dtenant=${{ matrix.tenant }} -DskipUnitTests -Dfailsafe.includes="**/${{ matrix.testClass }}.java"; then | |
| echo "β Tests passed on attempt $ATTEMPT!" | |
| EXIT_CODE=0 | |
| break | |
| else | |
| if [ $ATTEMPT -lt $MAX_RETRIES ]; then | |
| echo "β οΈ Attempt $ATTEMPT failed. Retrying in 30 seconds..." | |
| sleep 30 | |
| else | |
| echo "β All $MAX_RETRIES attempts failed for ${{ matrix.testClass }} - ${{ matrix.tokenFlow }} - ${{ matrix.tenant }}." | |
| fi | |
| fi | |
| done | |
| exit $EXIT_CODE | |
| - name: Upload test results π | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: test-results-${{ matrix.testClass }}-${{ matrix.tokenFlow }}-${{ matrix.tenant }} | |
| path: | | |
| sdm/target/surefire-reports/ | |
| sdm/target/failsafe-reports/ | |
| retention-days: 7 | |
| # Summary job to aggregate results | |
| test-summary: | |
| environment: dev | |
| runs-on: ubuntu-latest | |
| needs: integration-test | |
| if: always() && github.event.pull_request.merged == true | |
| steps: | |
| - name: Check test results π | |
| run: | | |
| if [ "${{ needs.integration-test.result }}" == "success" ]; then | |
| echo "β All integration tests passed!" | |
| else | |
| echo "β Some integration tests failed. Check individual job results for details." | |
| exit 1 | |
| fi |