Cypress #14562
This file contains 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: Cypress | |
on: | |
# allow running manually | |
workflow_dispatch: | |
pull_request: | |
branches: [ 'master', 'stable-*' ] | |
push: | |
branches: [ 'master', 'stable-*' ] | |
# daily on master | |
schedule: | |
- cron: '30 5 * * *' | |
concurrency: | |
group: cypress-${{ github.ref }} | |
cancel-in-progress: true | |
jobs: | |
cypress: | |
runs-on: ubuntu-latest | |
env: | |
# base of a PR, or pushed-to branch outside PRs, or master | |
BRANCH: ${{ github.base_ref || github.ref || 'refs/heads/master' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
test: | |
- 'approval' | |
- 'approval-modal' | |
- 'collections' | |
- 'community' | |
- 'namespaces' | |
- 'repo' | |
- 'screenshots' | |
steps: | |
# galaxykit needs pip 23+, Ubuntu 22.04's default Python uses pip 22 | |
- name: "Install python 3.11" | |
uses: actions/setup-python@v5 | |
with: | |
python-version: '3.11' | |
- name: "Install galaxykit dependency" | |
run: | | |
# pip install git+https://github.com/ansible/galaxykit.git@branch_name | |
pip install git+https://github.com/ansible/galaxykit.git | |
- name: "Set env.SHORT_BRANCH, BACKEND_FLAVOR" | |
run: | | |
SHORT_BRANCH=`sed 's/^refs\/heads\///' <<< $BRANCH` | |
case "${{ matrix.test }}" in | |
community*) | |
BACKEND_FLAVOR=community | |
API=api | |
;; | |
*) | |
BACKEND_FLAVOR=standalone | |
API=api/galaxy | |
;; | |
esac | |
echo "BACKEND_FLAVOR=${BACKEND_FLAVOR}" >> $GITHUB_ENV | |
echo "COMPOSE_INTERACTIVE_NO_CLI=1" >> $GITHUB_ENV | |
echo "SHORT_BRANCH=${SHORT_BRANCH}" >> $GITHUB_ENV | |
echo "API=${API}" >> $GITHUB_ENV | |
- name: "Set variables for screenshots" | |
if: matrix.test == 'screenshots' | |
run: | | |
UI_COMMIT_BASE=`curl -s https://api.github.com/repos/ansible/ansible-hub-ui/branches/${SHORT_BRANCH} | jq -r .commit.sha` | |
echo "UI_COMMIT_BASE=${UI_COMMIT_BASE}" >> $GITHUB_ENV | |
- name: "Checkout ansible-hub-ui (${{ github.ref }})" | |
uses: actions/checkout@v4 | |
with: | |
path: 'ansible-hub-ui' | |
- name: "Checkout galaxy_ng (${{ env.SHORT_BRANCH }})" | |
uses: actions/checkout@v4 | |
with: | |
repository: 'ansible/galaxy_ng' | |
ref: '${{ env.SHORT_BRANCH }}' | |
path: 'galaxy_ng' | |
- name: "Checkout oci_env (main)" | |
uses: actions/checkout@v4 | |
with: | |
repository: 'pulp/oci_env' | |
path: 'oci_env' | |
- name: "Configure oci_env" | |
working-directory: 'oci_env' | |
run: | | |
pip install --editable ./client/ | |
# merge common, profile-specific and test matrix specific config | |
cat ../ansible-hub-ui/.github/workflows/cypress/compose.env.common \ | |
../ansible-hub-ui/.github/workflows/cypress/compose.env."$BACKEND_FLAVOR" \ | |
../ansible-hub-ui/test/cypress/e2e/"${{ matrix.test }}"/compose.env \ | |
| sed 's/^\s\+//' | tee compose.env || [ -s compose.env ] | |
# oci-env compose build: FileNotFoundError: [Errno 2] No such file or directory: 'docker-compose' | |
- name: "Provide docker-compose" | |
run: | | |
mkdir -p /home/runner/.local/bin/ | |
cd /home/runner/.local/bin/ | |
( echo '#!/bin/sh' ; echo 'docker compose "$@"' ) > docker-compose | |
chmod +x docker-compose | |
- name: "oci-env compose build" | |
working-directory: 'oci_env' | |
run: 'oci-env compose build' | |
- name: "oci-env compose up" | |
working-directory: 'oci_env' | |
run: 'oci-env compose up &' | |
- name: "Install node 20" | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '20' | |
- name: "Cache ~/.npm & ~/.cache/Cypress" | |
uses: actions/cache@v4 | |
with: | |
path: | | |
~/.npm | |
~/.cache/Cypress | |
key: npm-${{ env.SHORT_BRANCH }}-${{ hashFiles('ansible-hub-ui/**/package-lock.json') }} | |
restore-keys: | | |
npm-${{ env.SHORT_BRANCH }}- | |
npm- | |
- name: 'npm install' | |
working-directory: 'ansible-hub-ui' | |
run: 'npm install' | |
- name: 'gettext extract & compile' | |
working-directory: 'ansible-hub-ui' | |
run: | | |
# production displays unknown translations literally, make sure it's up to date | |
npm run gettext:extract | |
npm run gettext:compile | |
- name: "Build standalone UI" | |
if: ${{ env.BACKEND_FLAVOR == 'standalone' }} | |
working-directory: 'ansible-hub-ui' | |
run: | | |
npm run build-standalone | |
# save the App.*.js hash for later verification | |
BUILD_HASH=`ls dist/js/App*js | cut -d. -f2` | |
echo "BUILD_HASH=${BUILD_HASH}" >> $GITHUB_ENV | |
- name: "Build community UI" | |
if: ${{ env.BACKEND_FLAVOR == 'community' }} | |
working-directory: 'ansible-hub-ui' | |
run: | | |
npm run build-community | |
# save the App.*.js hash for later verification | |
BUILD_HASH=`ls dist/js/App*js | cut -d. -f2` | |
echo "BUILD_HASH=${BUILD_HASH}" >> $GITHUB_ENV | |
- name: "Serve standalone UI" | |
if: ${{ env.BACKEND_FLAVOR == 'standalone' }} | |
run: | | |
mkdir -p www/static/ | |
mv ansible-hub-ui/dist www/static/galaxy_ng | |
cd www | |
echo '{}' > package.json | |
npm install local-web-server | |
node_modules/.bin/ws --port 8002 --directory . --spa static/galaxy_ng/index.html \ | |
--rewrite '/api/(.*) -> http://localhost:5001/api/$1' \ | |
--rewrite '/pulp/api/(.*) -> http://localhost:5001/pulp/api/$1' \ | |
--rewrite '/v2/(.*) -> http://localhost:5001/v2/$1' \ | |
--rewrite '/extensions/v2/(.*) -> http://localhost:5001/extensions/v2/$1' & | |
- name: "Serve community UI" | |
if: ${{ env.BACKEND_FLAVOR == 'community' }} | |
run: | | |
mkdir -p www/ | |
mv ansible-hub-ui/dist/* www/ | |
cd www | |
echo '{}' > package.json | |
npm install local-web-server | |
node_modules/.bin/ws --port 8002 --directory . --spa index.html \ | |
--rewrite '/api/(.*) -> http://localhost:5001/api/$1' \ | |
--rewrite '/pulp/api/(.*) -> http://localhost:5001/pulp/api/$1' \ | |
--rewrite '/v2/(.*) -> http://localhost:5001/v2/$1' \ | |
--rewrite '/extensions/v2/(.*) -> http://localhost:5001/extensions/v2/$1' & | |
- name: "Install Cypress & test dependencies" | |
working-directory: 'ansible-hub-ui/test' | |
run: | | |
npm install | |
- name: "Install Imagemagick" | |
if: matrix.test == 'screenshots' | |
run: | | |
sudo apt install imagemagick | |
- name: "Configure Cypress" | |
working-directory: 'ansible-hub-ui/test' | |
run: | | |
cp -aiv ../.github/workflows/cypress/cypress.env.json."$BACKEND_FLAVOR" cypress.env.json | |
- name: "Ensure standalone index.html uses the new js" | |
if: ${{ env.BACKEND_FLAVOR == 'standalone' }} | |
run: | | |
echo 'expecting /static/galaxy_ng/js/App.'"$BUILD_HASH"'.js' | |
curl http://localhost:8002/static/galaxy_ng/index.html | tee /dev/stderr | grep '/static/galaxy_ng/js/App.'"$BUILD_HASH"'.js' | |
- name: "Ensure community index.html uses the new js" | |
if: ${{ env.BACKEND_FLAVOR == 'community' }} | |
run: | | |
echo 'expecting /js/App.'"$BUILD_HASH"'.js' | |
curl http://localhost:8002/index.html | tee /dev/stderr | grep '/js/App.'"$BUILD_HASH"'.js' | |
- name: "Ensure galaxykit can connect to API" | |
run: | | |
galaxykit -s http://localhost:8002/"$API"/ -u admin -p admin collection list | |
- name: "Check initial feature flags" | |
run: | | |
curl -s http://localhost:5001/"$API"/_ui/v1/feature-flags/ | jq | |
- name: "Check component versions & settings" | |
run: | | |
HUB_TOKEN=`curl -s -u admin:admin -d '' http://localhost:5001/"$API"/v3/auth/token/ | jq -r .token` | |
curl -s -H "Authorization: Token $HUB_TOKEN" http://localhost:5001/"$API"/ | jq | |
curl -s -H "Authorization: Token $HUB_TOKEN" http://localhost:5001/"$API"/_ui/v1/settings/ | jq | |
- name: "Check if e2e contains only dirs in matrix test array" | |
working-directory: 'ansible-hub-ui' | |
run: | | |
diff -Naur <(ls test/cypress/e2e | sort) <(yq '.jobs.cypress.strategy.matrix.test[]' .github/workflows/cypress.yml | sort) | |
- name: "Cache base screenshots" | |
if: matrix.test == 'screenshots' | |
uses: actions/cache@v4 | |
with: | |
path: ansible-hub-ui/test/screenshots-base/ | |
key: screenshots-${{env.SHORT_BRANCH}}-${{ env.UI_COMMIT_BASE }} | |
restore-keys: | | |
screenshots-${{env.SHORT_BRANCH}}- | |
- name: "List cached screenshots" | |
if: ${{ matrix.test == 'screenshots' && github.event_name == 'pull_request' }} | |
run: | | |
ls ansible-hub-ui/test/screenshots-base/ | |
- name: "Run cypress" | |
working-directory: 'ansible-hub-ui/test' | |
env: | |
CONSOLE_LOG_TO_TERMINAL: true | |
run: | | |
sed -i '/specPattern:/s/\*\*/${{matrix.test}}/' cypress.config.js | |
sed -i "/screenshotsFolder:/s/',$/\/${{matrix.test}}',/" cypress.config.js | |
git diff cypress.config.js | |
npm run cypress:chrome | |
- name: "List new screenshots" | |
if: matrix.test == 'screenshots' | |
continue-on-error: true | |
run: | | |
ls ansible-hub-ui/test/cypress/screenshots/screenshots/screenshots.js/ | |
- name: "Compare screenshots" | |
if: ${{ matrix.test == 'screenshots' && github.event_name == 'pull_request' }} | |
working-directory: 'ansible-hub-ui/test' | |
run: | | |
changed=false | |
for orig in screenshots-base/*; do | |
name=`basename "$orig"` | |
new="cypress/screenshots/screenshots/screenshots.js/$name" | |
diff="cypress/screenshots/screenshots/diff--$name" | |
num=$(compare -metric RMSE -fuzz 5% "$orig" "$new" "$diff" 2>&1 | awk '{ print $1 }') | |
num=${num%.*} | |
if [ "$num" -gt 64 ]; then | |
echo "screenshot $name changed: $num" 1>&2 | |
changed=true | |
fi | |
done | |
if [ "$changed" = true ]; then | |
cp -a screenshots-base cypress/screenshots/screenshots/0-before | |
mv cypress/screenshots/screenshots/{screenshots.js,1-after} | |
exit 1 | |
fi | |
- name: "Move screenshots to cache" | |
if: ${{ matrix.test == 'screenshots' && github.event_name != 'pull_request' }} | |
working-directory: 'ansible-hub-ui/test' | |
run: | | |
rm -rf screenshots-base/ | |
mv cypress/screenshots/screenshots/screenshots.js ./screenshots-base | |
- uses: actions/upload-artifact@v4 | |
if: failure() | |
with: | |
name: screenshots_and_videos-${{matrix.test}} | |
path: | | |
ansible-hub-ui/test/cypress/screenshots | |
ansible-hub-ui/test/cypress/videos | |
- name: "Kill container, show debug info" | |
if: always() | |
working-directory: 'oci_env' | |
run: | | |
oci-env exec bash -c "pip3 list && pip3 install pipdeptree && pipdeptree" | |
oci-env compose logs | |
oci-env compose kill |