From 37e45ab2e69edf6da6446a2cc3dc01e2af1abb53 Mon Sep 17 00:00:00 2001 From: David Dieulivol <ddieulivol@gitlab.com> Date: Wed, 26 Apr 2023 14:29:45 +0000 Subject: [PATCH] Extract package helpers to its own file gitlab_component_helpers.sh relies on several ENV variables only present in the CI. Extracting this file will make it easier to reuse those package functions outside of the CI. --- .../testing_guide/frontend_testing.md | 20 +++++++ jest_resolver.js | 2 +- scripts/frontend/download_fixtures.sh | 56 +++++++++++++++++ scripts/gitlab_component_helpers.sh | 60 +------------------ scripts/packages/helpers.sh | 59 ++++++++++++++++++ spec/frontend/__helpers__/fixtures.js | 5 +- spec/frontend_integration/README.md | 2 + 7 files changed, 145 insertions(+), 59 deletions(-) create mode 100755 scripts/frontend/download_fixtures.sh create mode 100644 scripts/packages/helpers.sh diff --git a/doc/development/testing_guide/frontend_testing.md b/doc/development/testing_guide/frontend_testing.md index a3b580a43fa1..ba965ab204ab 100644 --- a/doc/development/testing_guide/frontend_testing.md +++ b/doc/development/testing_guide/frontend_testing.md @@ -894,6 +894,26 @@ You can generate fixtures by running: You can find generated fixtures are in `tmp/tests/frontend/fixtures-ee`. +### Download fixtures + +We generate fixtures in GitLab CI, and store them in the package registry. + +The `scripts/frontend/download_fixtures.sh` script is meant to download and extract those fixtures for local use: + +```shell +# Checks if a frontend fixture package exists in the gitlab-org/gitlab +# package registry by looking at the commits on a local branch. +# +# The package is downloaded and extracted if it exists +$ scripts/frontend/download_fixtures.sh + +# Same as above, but only looks at the last 10 commits of the currently checked-out branch +$ scripts/frontend/download_fixtures.sh --max-commits=10 + +# Looks at the commits on the local master branch instead of the currently checked-out branch +$ scripts/frontend/download_fixtures.sh --branch master +``` + #### Creating new fixtures For each fixture, you can find the content of the `response` variable in the output file. diff --git a/jest_resolver.js b/jest_resolver.js index 6cbc1b9f18fe..66434ca7a6c0 100644 --- a/jest_resolver.js +++ b/jest_resolver.js @@ -9,7 +9,7 @@ module.exports = (request, options) => { console.error( '\x1b[1m\x1b[41m\x1b[30m %s \x1b[0m %s', '!', - `Fixture file ${request} does not exist. Did you run bin/rake frontend:fixtures?`, + `Fixture file ${request} does not exist. Did you run bin/rake frontend:fixtures? You can also download fixtures from the gitlab-org/gitlab package registry. See the Fixtures docs for more info.`, ); } throw e; diff --git a/scripts/frontend/download_fixtures.sh b/scripts/frontend/download_fixtures.sh new file mode 100755 index 000000000000..47a57401bb95 --- /dev/null +++ b/scripts/frontend/download_fixtures.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +# +# Downloads the most recent frontend fixtures for the current commit, going up the commit parent +# chain up to max-commits commits (defaults to 50 commits). +# + +source scripts/packages/helpers.sh + +print_help() { + echo "Usage: scripts/frontend/download_fixtures.sh [--branch <branch-name>] [--max-commits <number>]" + echo + echo "Looks for a frontend fixture package in the package registry for commits on a local branch." + echo + echo "If --branch isn't specified, the script will use the current branch as a commit reference." + echo "If --max-commits isn't specified, the default is 50 commits." + + return +} + +branch="HEAD" +max_commits_count=50 + +while [ $# -gt 0 ]; do + case "$1" in + --branch) + shift + branch="$1" + ;; + --max-commits) + shift + max_commits_count="$1" + ;; + *) + print_help + exit + ;; + esac + shift +done + +for commit_sha in $(git rev-list ${branch} --max-count="${max_commits_count}"); do + API_PACKAGES_BASE_URL=https://gitlab.com/api/v4/projects/278964/packages/generic + FIXTURES_PACKAGE="fixtures-${commit_sha}.tar.gz" + FIXTURES_PACKAGE_URL="${API_PACKAGES_BASE_URL}/fixtures/${commit_sha}/${FIXTURES_PACKAGE}" + + echo "Looking for frontend fixtures for commit ${commit_sha}..." + + if ! archive_doesnt_exist "${FIXTURES_PACKAGE_URL}" > /dev/null 2>&1; then + echo "We have found frontend fixtures at ${FIXTURES_PACKAGE_URL}!" + + read_curl_package "${FIXTURES_PACKAGE_URL}" | extract_package + + break + fi +done diff --git a/scripts/gitlab_component_helpers.sh b/scripts/gitlab_component_helpers.sh index 301d4fb5d37f..f25998a6c055 100644 --- a/scripts/gitlab_component_helpers.sh +++ b/scripts/gitlab_component_helpers.sh @@ -2,6 +2,9 @@ set -euo pipefail +# Generic helper functions for archives/packages +source scripts/packages/helpers.sh + export CURL_TOKEN_HEADER="${CURL_TOKEN_HEADER:-"JOB-TOKEN"}" export GITLAB_COM_CANONICAL_PROJECT_ID="278964" # https://gitlab.com/gitlab-org/gitlab @@ -54,63 +57,6 @@ export GITLAB_ASSETS_PACKAGE_URL="${API_PACKAGES_BASE_URL}/assets/${NODE_ENV}-${ # Fixtures constants export FIXTURES_PATH="tmp/tests/frontend/**/*" -# Generic helper functions -function archive_doesnt_exist() { - local package_url="${1}" - - status=$(curl -I --silent --retry 3 --output /dev/null -w "%{http_code}" "${package_url}") - - if [[ "${status}" = "200" ]]; then - echoinfo "The archive was found. The server returned status ${status}." - return 1 - else - echoinfo "The archive was not found. The server returned status ${status}." - return 0 - fi -} - -function create_package() { - local archive_filename="${1}" - local paths_to_archive="${2}" - local tar_working_folder="${3:-.}" - - echoinfo "Running 'tar -czvf ${archive_filename} -C ${tar_working_folder} ${paths_to_archive}'" - tar -czf ${archive_filename} -C ${tar_working_folder} ${paths_to_archive} - du -h ${archive_filename} -} - -function upload_package() { - local archive_filename="${1}" - local package_url="${2}" - local token_header="${CURL_TOKEN_HEADER}" - local token="${CI_JOB_TOKEN}" - - if [[ "${UPLOAD_PACKAGE_FLAG}" = "false" ]]; then - echoerr "The archive ${archive_filename} isn't supposed to be uploaded for this instance (${CI_SERVER_HOST}) & project (${CI_PROJECT_PATH})!" - exit 1 - fi - - echoinfo "Uploading ${archive_filename} to ${package_url} ..." - curl --fail --silent --retry 3 --header "${token_header}: ${token}" --upload-file "${archive_filename}" "${package_url}" -} - -function read_curl_package() { - local package_url="${1}" - - echoinfo "Downloading from ${package_url} ..." - - curl --fail --silent --retry 3 "${package_url}" -} - -function extract_package() { - local tar_working_folder="${1:-.}" - mkdir -p "${tar_working_folder}" - - echoinfo "Extracting archive to ${tar_working_folder}" - - tar -xz -C ${tar_working_folder} < /dev/stdin -} - # Workhorse functions function gitlab_workhorse_archive_doesnt_exist() { archive_doesnt_exist "${GITLAB_WORKHORSE_PACKAGE_URL}" diff --git a/scripts/packages/helpers.sh b/scripts/packages/helpers.sh new file mode 100644 index 000000000000..2917338aeb8f --- /dev/null +++ b/scripts/packages/helpers.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +source scripts/utils.sh + +function archive_doesnt_exist() { + local package_url="${1}" + + status=$(curl -I --silent --retry 3 --output /dev/null -w "%{http_code}" "${package_url}") + + if [[ "${status}" = "200" ]]; then + echoinfo "The archive was found. The server returned status ${status}." + return 1 + else + echoinfo "The archive was not found. The server returned status ${status}." + return 0 + fi +} + +function create_package() { + local archive_filename="${1}" + local paths_to_archive="${2}" + local tar_working_folder="${3:-.}" + + echoinfo "Running 'tar -czvf ${archive_filename} -C ${tar_working_folder} ${paths_to_archive}'" + tar -czf ${archive_filename} -C ${tar_working_folder} ${paths_to_archive} + du -h ${archive_filename} +} + +function upload_package() { + local archive_filename="${1}" + local package_url="${2}" + local token_header="${CURL_TOKEN_HEADER}" + local token="${CI_JOB_TOKEN}" + + if [[ "${UPLOAD_PACKAGE_FLAG}" = "false" ]]; then + echoerr "The archive ${archive_filename} isn't supposed to be uploaded for this instance (${CI_SERVER_HOST}) & project (${CI_PROJECT_PATH})!" + exit 1 + fi + + echoinfo "Uploading ${archive_filename} to ${package_url} ..." + curl --fail --silent --retry 3 --header "${token_header}: ${token}" --upload-file "${archive_filename}" "${package_url}" +} + +function read_curl_package() { + local package_url="${1}" + + echoinfo "Downloading from ${package_url} ..." + + curl --fail --silent --retry 3 "${package_url}" +} + +function extract_package() { + local tar_working_folder="${1:-.}" + mkdir -p "${tar_working_folder}" + + echoinfo "Extracting archive to ${tar_working_folder}" + + tar -xz -C ${tar_working_folder} < /dev/stdin +} diff --git a/spec/frontend/__helpers__/fixtures.js b/spec/frontend/__helpers__/fixtures.js index a6f7b37161e1..c66411979e95 100644 --- a/spec/frontend/__helpers__/fixtures.js +++ b/spec/frontend/__helpers__/fixtures.js @@ -12,7 +12,10 @@ export function getFixture(relativePath) { throw new ErrorWithStack( `Fixture file ${relativePath} does not exist. -Did you run bin/rake frontend:fixtures?`, +Did you run bin/rake frontend:fixtures? You can also download fixtures from the gitlab-org/gitlab package registry. + +See https://docs.gitlab.com/ee/development/testing_guide/frontend_testing.html#download-fixtures for more info. +`, getFixture, ); } diff --git a/spec/frontend_integration/README.md b/spec/frontend_integration/README.md index 377294fb19fc..ee7601133077 100644 --- a/spec/frontend_integration/README.md +++ b/spec/frontend_integration/README.md @@ -22,6 +22,8 @@ We can generate the necessary fixtures and GraphQL schema by running: bundle exec rake frontend:fixtures gitlab:graphql:schema:dump ``` +You can also download those fixtures from the package registry: see [download fixtures](https://docs.gitlab.com/ee/development/testing_guide/frontend_testing.html#download-fixtures) for more info. + Then we can use [Jest](https://jestjs.io/) to run the frontend integration tests: ```shell -- GitLab