Files- text treatment #97
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
| # DSpace Continuous Integration/Build via GitHub Actions | |
| # Concepts borrowed from | |
| # https://docs.github.com/en/free-pro-team@latest/actions/guides/building-and-testing-nodejs | |
| name: Build | |
| # Run this Build for all pushes / PRs to current branch | |
| on: [push, pull_request] | |
| permissions: | |
| contents: read # to fetch code (actions/checkout) | |
| packages: read # to fetch private images from GitHub Container Registry (GHCR) | |
| jobs: | |
| tests: | |
| runs-on: ubuntu-latest | |
| env: | |
| CI: true # Set at job level | |
| # The ci step will test the dspace-angular code against DSpace REST. | |
| # Direct that step to utilize a DSpace REST service that has been started in docker. | |
| # NOTE: These settings should be kept in sync with those in [src]/docker/docker-compose-ci.yml | |
| DSPACE_REST_HOST: 127.0.0.1 | |
| DSPACE_REST_PORT: 8080 | |
| DSPACE_REST_NAMESPACE: '/server' | |
| DSPACE_REST_SSL: false | |
| # Spin up UI on 127.0.0.1 to avoid host resolution issues in e2e tests with Node 18+ | |
| DSPACE_UI_HOST: 127.0.0.1 | |
| DSPACE_UI_PORT: 4000 | |
| # Ensure all SSR caching is disabled in test environment | |
| DSPACE_CACHE_SERVERSIDE_BOTCACHE_MAX: 0 | |
| DSPACE_CACHE_SERVERSIDE_ANONYMOUSCACHE_MAX: 0 | |
| # Tell Cypress to run e2e tests using the same UI URL | |
| CYPRESS_BASE_URL: http://127.0.0.1:4000 | |
| # Disable the cookie consent banner in e2e tests to avoid errors because of elements hidden by it | |
| DSPACE_INFO_ENABLECOOKIECONSENTPOPUP: false | |
| # When Chrome version is specified, we pin to a specific version of Chrome | |
| # Comment this out to use the latest release | |
| #CHROME_VERSION: "90.0.4430.212-1" | |
| # Bump Node heap size (OOM in CI after upgrading to Angular 15) | |
| NODE_OPTIONS: '--max-old-space-size=4096' | |
| # Project name to use when running "docker compose" prior to e2e tests | |
| COMPOSE_PROJECT_NAME: 'ci' | |
| # Docker Registry to use for Docker compose scripts below. | |
| # We use GitHub's Container Registry to avoid aggressive rate limits at DockerHub. | |
| DOCKER_REGISTRY: docker.io | |
| strategy: | |
| # Create a matrix of Node versions to test against (in parallel) | |
| matrix: | |
| node-version: [18.x, 20.x] | |
| # Do NOT exit immediately if one matrix job fails | |
| fail-fast: false | |
| # These are the actual CI steps to perform per job | |
| steps: | |
| # https://github.com/actions/checkout | |
| - name: Checkout codebase | |
| uses: actions/checkout@v4 | |
| # https://github.com/actions/setup-node | |
| - name: Install Node.js ${{ matrix.node-version }} | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| # If CHROME_VERSION env variable specified above, then pin to that version. | |
| # Otherwise, just install latest version of Chrome. | |
| - name: Install Chrome (for e2e tests) | |
| run: | | |
| if [[ -z "${CHROME_VERSION}" ]] | |
| then | |
| echo "Installing latest stable version" | |
| sudo apt-get update | |
| sudo apt-get --only-upgrade install google-chrome-stable -y | |
| else | |
| echo "Installing version ${CHROME_VERSION}" | |
| wget -q "https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_${CHROME_VERSION}_amd64.deb" | |
| sudo dpkg -i "google-chrome-stable_${CHROME_VERSION}_amd64.deb" | |
| fi | |
| google-chrome --version | |
| # https://github.com/actions/cache/blob/main/examples.md#node---yarn | |
| - name: Get Yarn cache directory | |
| id: yarn-cache-dir-path | |
| run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT | |
| - name: Cache Yarn dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| # Cache entire Yarn cache directory (see previous step) | |
| path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | |
| # Cache key is hash of yarn.lock. Therefore changes to yarn.lock will invalidate cache | |
| key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} | |
| restore-keys: ${{ runner.os }}-yarn- | |
| - name: Install Yarn dependencies | |
| run: yarn install --frozen-lockfile | |
| - name: Build lint plugins | |
| run: yarn run build:lint | |
| - name: Run lint plugin tests | |
| run: yarn run test:lint:nobuild | |
| - name: Run lint | |
| run: yarn run lint:nobuild --quiet | |
| - name: Check for circular dependencies | |
| run: yarn run check-circ-deps | |
| - name: Run build | |
| run: yarn run build:prod | |
| - name: Run specs (unit tests) | |
| run: yarn run test:headless | |
| env: | |
| CI: true | |
| # Using "docker compose" start backend using CI configuration | |
| # and load assetstore from a cached copy | |
| - name: Start DSpace REST Backend via Docker (for e2e tests) | |
| run: | | |
| docker compose -f ./docker/docker-compose-ci.yml up -d | |
| docker compose -f ./docker/cli.yml -f ./docker/cli.assetstore.yml run --rm dspace-cli | |
| docker container ls | |
| - name: Create Test Data | |
| id: testdata | |
| run: | | |
| chmod +x scripts/create-test-data.sh | |
| ./scripts/create-test-data.sh | |
| env: | |
| DSPACE_REST_URL: http://localhost:8080/server | |
| DSPACE_ADMIN_EMAIL: [email protected] | |
| DSPACE_ADMIN_PASS: dspace | |
| - name: Update Field Config with Collection Handles | |
| run: | | |
| echo "Updating item-field-config.ts with actual handles..." | |
| # Get all collection handles from test data output | |
| JONES_HANDLE="${{ steps.testdata.outputs.jones_collection_handle }}" | |
| RELICS_HANDLE="${{ steps.testdata.outputs.relics_collection_handle }}" | |
| LAEFER_HANDLE="${{ steps.testdata.outputs.laefer_collection_handle }}" | |
| TANDON_HANDLE="${{ steps.testdata.outputs.tandon_collection_handle }}" | |
| TANDONCAPSTONE_HANDLE="${{ steps.testdata.outputs.tandoncapstone_collection_handle }}" | |
| DNP_HANDLE="${{ steps.testdata.outputs.dnp_collection_handle }}" | |
| CALABASH_HANDLE="${{ steps.testdata.outputs.calabash_collection_handle }}" | |
| OPENSCHOLARSHIP_HANDLE="${{ steps.testdata.outputs.openscholarship_collection_handle }}" | |
| SYLLABI_HANDLE="${{ steps.testdata.outputs.syllabi_collection_handle }}" | |
| echo "Jones Handle: $JONES_HANDLE" | |
| echo "Relics Handle: $RELICS_HANDLE" | |
| # Update the config file with actual handles | |
| sed -i "s|handles: \['JONES_HANDLE'\]|handles: ['$JONES_HANDLE']|g" \ | |
| src/themes/fda/app/item-page/field-config/item-field-config.ts | |
| sed -i "s|handles: \['RELICS_HANDLE'\]|handles: ['$RELICS_HANDLE']|g" \ | |
| src/themes/fda/app/item-page/field-config/item-field-config.ts | |
| sed -i "s|handles: \['LAEFER_HANDLE'\]|handles: ['$LAEFER_HANDLE']|g" \ | |
| src/themes/fda/app/item-page/field-config/item-field-config.ts | |
| sed -i "s|handles: \['TANDON_HANDLE'\]|handles: ['$TANDON_HANDLE']|g" \ | |
| src/themes/fda/app/item-page/field-config/item-field-config.ts | |
| sed -i "s|handles: \['TANDONCAPSTONE_HANDLE'\]|handles: ['$TANDONCAPSTONE_HANDLE']|g" \ | |
| src/themes/fda/app/item-page/field-config/item-field-config.ts | |
| sed -i "s|handles: \['DNP_HANDLE'\]|handles: ['$DNP_HANDLE']|g" \ | |
| src/themes/fda/app/item-page/field-config/item-field-config.ts | |
| sed -i "s|handles: \['CALABASH_HANDLE'\]|handles: ['$CALABASH_HANDLE']|g" \ | |
| src/themes/fda/app/item-page/field-config/item-field-config.ts | |
| sed -i "s|handles: \['OPENSCHOLARSHIP_HANDLE'\]|handles: ['$OPENSCHOLARSHIP_HANDLE']|g" \ | |
| src/themes/fda/app/item-page/field-config/item-field-config.ts | |
| sed -i "s|handles: \['SYLLABI_HANDLE'\]|handles: ['$SYLLABI_HANDLE']|g" \ | |
| src/themes/fda/app/item-page/field-config/item-field-config.ts | |
| echo "Updated config file:" | |
| grep -A2 "handles:" src/themes/fda/app/item-page/field-config/item-field-config.ts || true | |
| # Run integration tests via Cypress.io | |
| # https://github.com/cypress-io/github-action | |
| # (NOTE: to run these e2e tests locally, just use 'ng e2e') | |
| - name: Run e2e tests (integration tests) | |
| uses: cypress-io/github-action@v6 | |
| with: | |
| # Run tests in Chrome, headless mode (default) | |
| browser: chrome | |
| # Start app before running tests (will be stopped automatically after tests finish) | |
| start: yarn run serve:ssr | |
| # Wait for backend & frontend to be available | |
| # NOTE: We use the 'sites' REST endpoint to also ensure the database is ready | |
| wait-on: http://127.0.0.1:8080/server/api/core/sites, http://127.0.0.1:4000 | |
| # Wait for 2 mins max for everything to respond | |
| wait-on-timeout: 120 | |
| # Don't reinstall dependencies | |
| install: false | |
| env: | |
| # Pass test data UUIDs to Cypress | |
| CYPRESS_DSPACE_TEST_FDA_DEFAULT_ITEM: ${{ steps.testdata.outputs.default_item_uuid }} | |
| CYPRESS_DSPACE_TEST_JONES_ITEM: ${{ steps.testdata.outputs.jones_item_uuid }} | |
| CYPRESS_DSPACE_TEST_RELICS_ITEM: ${{ steps.testdata.outputs.relics_item_uuid }} | |
| CYPRESS_DSPACE_TEST_LAEFER_ITEM: ${{ steps.testdata.outputs.laefer_item_uuid }} | |
| CYPRESS_DSPACE_TEST_TANDON_ITEM: ${{ steps.testdata.outputs.tandon_item_uuid }} | |
| CYPRESS_DSPACE_TEST_TANDONCAPSTONE_ITEM: ${{ steps.testdata.outputs.tandoncapstone_item_uuid }} | |
| CYPRESS_DSPACE_TEST_DNP_ITEM: ${{ steps.testdata.outputs.dnp_item_uuid }} | |
| CYPRESS_DSPACE_TEST_CALABASH_ITEM: ${{ steps.testdata.outputs.calabash_item_uuid }} | |
| CYPRESS_DSPACE_TEST_OPENSCHOLARSHIP_ITEM: ${{ steps.testdata.outputs.openscholarship_item_uuid }} | |
| CYPRESS_DSPACE_TEST_SYLLABI_ITEM: ${{ steps.testdata.outputs.syllabi_item_uuid }} | |
| # If e2e tests fail, Cypress creates a screenshot of what happened | |
| # Save those in an Artifact | |
| - name: Upload e2e test failure screenshots to Artifacts | |
| uses: actions/upload-artifact@v4 | |
| if: failure() | |
| with: | |
| name: e2e-test-screenshots-${{ matrix.node-version }} | |
| path: cypress/screenshots | |
| - name: Stop app (in case it stays up after e2e tests) | |
| run: | | |
| app_pid=$(lsof -t -i:4000) | |
| if [[ ! -z $app_pid ]]; then | |
| echo "App was still up! (PID: $app_pid)" | |
| kill -9 $app_pid | |
| fi | |
| # Start up the app with SSR enabled (run in background) | |
| - name: Start app in SSR (server-side rendering) mode | |
| run: | | |
| nohup yarn run serve:ssr & | |
| printf 'Waiting for app to start' | |
| until curl --output /dev/null --silent --head --fail http://127.0.0.1:4000/home; do | |
| printf '.' | |
| sleep 2 | |
| done | |
| echo "App started successfully." | |
| # Get homepage and verify that the <meta name="title"> tag includes "DSpace". | |
| # If it does, then SSR is working, as this tag is created by our MetadataService. | |
| # This step also prints entire HTML of homepage for easier debugging if grep fails. | |
| - name: Verify SSR (server-side rendering) on Homepage | |
| run: | | |
| result=$(wget -O- -q http://127.0.0.1:4000/home) | |
| echo "$result" | |
| echo "$result" | grep -oE "<meta name=\"title\" [^>]*>" | grep Digital | |
| # Verify 301 Handle redirect behavior | |
| # Note: /handle/123456789/260 is the same test Publication used by our e2e tests | |
| - name: Verify 301 redirect from '/handle' URLs | |
| run: | | |
| result=$(wget --server-response --quiet http://127.0.0.1:4000/handle/123456789/260 2>&1 | head -1 | awk '{print $2}') | |
| echo "$result" | |
| [[ "$result" -eq "301" ]] | |
| # Verify 403 error code behavior | |
| - name: Verify 403 error code from '/403' | |
| run: | | |
| result=$(wget --server-response --quiet http://127.0.0.1:4000/403 2>&1 | head -1 | awk '{print $2}') | |
| echo "$result" | |
| [[ "$result" -eq "403" ]] | |
| # Verify 404 error code behavior | |
| - name: Verify 404 error code from '/404' and on invalid pages | |
| run: | | |
| result=$(wget --server-response --quiet http://127.0.0.1:4000/404 2>&1 | head -1 | awk '{print $2}') | |
| echo "$result" | |
| result2=$(wget --server-response --quiet http://127.0.0.1:4000/invalidurl 2>&1 | head -1 | awk '{print $2}') | |
| echo "$result2" | |
| [[ "$result" -eq "404" && "$result2" -eq "404" ]] | |
| # Verify 500 error code behavior | |
| - name: Verify 500 error code from '/500' | |
| run: | | |
| result=$(wget --server-response --quiet http://127.0.0.1:4000/500 2>&1 | head -1 | awk '{print $2}') | |
| echo "$result" | |
| [[ "$result" -eq "500" ]] | |
| - name: Stop running app | |
| run: kill -9 $(lsof -t -i:4000) | |
| - name: Shutdown Docker containers | |
| run: docker compose -f ./docker/docker-compose-ci.yml down | |