From 2117e325345d7e79059734aee989cc6d9334d1f0 Mon Sep 17 00:00:00 2001 From: Zak Burke Date: Thu, 11 Nov 2021 23:27:53 -0500 Subject: [PATCH] migrate from Jenkins to GitHub Actions for b6.0 (#791) `v6.0.0` was published via Jenkins and then builds were ported to GA. Now, the `v6.0.1` build based on the `b6.0` branch split from the `v6.0.0` tag is failing unexpectedly. This PR migrates the branch to GA with the fond fond hope that the release build will succeed here. --- .github/workflows/build-npm-release.yml | 244 ++++++++++++++++++++++++ .github/workflows/build-npm.yml | 199 +++++++++++++++++++ Jenkinsfile => Jenkinsfile.deprecated | 0 package.json | 5 +- 4 files changed, 447 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/build-npm-release.yml create mode 100644 .github/workflows/build-npm.yml rename Jenkinsfile => Jenkinsfile.deprecated (100%) diff --git a/.github/workflows/build-npm-release.yml b/.github/workflows/build-npm-release.yml new file mode 100644 index 00000000..2624d8c0 --- /dev/null +++ b/.github/workflows/build-npm-release.yml @@ -0,0 +1,244 @@ +# This workflow will do a clean install of node dependencies, build the source code, +# run unit tests, perform a SonarCloud scan and publish NPM package ONLY on a tagged release. + +# For more information see: +# https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +# Common FOLIO configurable env: +# - YARN_TEST_OPTIONS (options to pass to 'yarn test') +# - SQ_ROOT_DIR (root SQ directory to scan relative to top-level directory) +# - PUBLISH_MOD_DESCRIPTOR (boolean 'true' or 'false') +# - COMPILE_TRANSLATION_FILES (boolean 'true' or 'false') + +name: buildNPM Release +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+*' + workflow_dispatch: + +jobs: + github-actions-ci: + if : ${{ startsWith(github.ref, 'refs/tags/v') }} + env: + YARN_TEST_OPTIONS: '--karma.singleRun --karma.browsers ChromeDocker --karma.reporters mocha junit --coverage' + SQ_ROOT_DIR: './src' + COMPILE_TRANSLATION_FILES: 'true' + PUBLISH_MOD_DESCRIPTOR: 'true' + FOLIO_NPM_REGISTRY: 'https://repository.folio.org/repository/npm-folio/' + FOLIO_MD_REGISTRY: 'https://folio-registry.dev.folio.org' + NODEJS_VERSION: '12' + JEST_JUNIT_OUTPUT_DIR: 'artifacts/jest-junit' + JEST_COVERAGE_REPORT_DIR: 'artifacts/coverage-jest/lcov-report/' + BIGTEST_JUNIT_OUTPUT_DIR: 'artifacts/runTest' + BIGTEST_COVERAGE_REPORT_DIR: 'artifacts/coverage/lcov-report/' + OKAPI_PULL: '{ "urls" : [ "https://folio-registry.dev.folio.org" ] }' + SQ_LCOV_REPORT: 'artifacts/coverage-jest/lcov.info' + SQ_EXCLUSIONS: '**/platform/alias-service.js,**/docs/**,**/node_modules/**,**/examples/**,**/artifacts/**,**/ci/**,Jenkinsfile,**/LICENSE,**/*.css,**/*.md,**/*.json,**/tests/**,**/stories/*.js,**/test/**,**/.stories.js,**/resources/bigtest/interactors/**,**/resources/bigtest/network/**,**/*-test.js,**/*.test.js,**/*-spec.js,**/karma.conf.js,**/jest.config.js' + + runs-on: ubuntu-latest + steps: + - uses: folio-org/checkout@v2 + with: + fetch-depth: 0 + + # Runs a single command using the runners shell + - name: Print tag info + run: echo "Building release tag, ${GITHUB_REF}" + + - name: Set TAG_VERSION + run: echo "TAG_VERSION=$(echo ${GITHUB_REF#refs/tags/v})" >> $GITHUB_ENV + + - name: Get version from package.json + id: package_version + uses: notiz-dev/github-action-json-property@release + with: + path: 'package.json' + prop_path: 'version' + + - name: Check matching tag and version in package.json + if: ${{ env.TAG_VERSION != steps.package_version.outputs.prop }} + run: | + echo "Tag version, ${TAG_VERSION}, does not match package.json version, ${PACKAGE_VERSION}." + exit 1 + env: + PACKAGE_VERSION: ${{ steps.package_version.outputs.prop }} + + - name: Setup kernel for react native, increase watchers + run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p + - name: Use Node.js + uses: actions/setup-node@v2 + with: + node-version: ${{ env.NODEJS_VERSION }} + check-latest: true + always-auth: true + + - name: Set yarn config + run: yarn config set @folio:registry $FOLIO_NPM_REGISTRY + + - name: Run yarn install + run: yarn install --ignore-scripts + + - name: Run yarn list + run: yarn list --pattern @folio + + - name: Run yarn lint + run: yarn lint + continue-on-error: true + + - name: Run yarn test + run: xvfb-run --server-args="-screen 0 1024x768x24" yarn test $YARN_TEST_OPTIONS + + - name: Run yarn formatjs-compile + if : ${{ env.COMPILE_TRANSLATION_FILES == 'true' }} + run: yarn formatjs-compile + + - name: Generate FOLIO module descriptor + if: ${{ env.PUBLISH_MOD_DESCRIPTOR == 'true' }} + run: yarn build-mod-descriptor + + - name: Print FOLIO module descriptor + if: ${{ env.PUBLISH_MOD_DESCRIPTOR == 'true' }} + run: cat module-descriptor.json + + - name: Read module descriptor + if: ${{ env.PUBLISH_MOD_DESCRIPTOR == 'true' }} + id: moduleDescriptor + uses: juliangruber/read-file-action@v1 + with: + path: ./module-descriptor.json + + - name: Docker registry login + run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login https://docker.io/v2/ -u "${{ secrets.DOCKER_USER }}" --password-stdin + + - name: Start a local instance of Okapi + if: ${{ env.PUBLISH_MOD_DESCRIPTOR == 'true' }} + run: | + docker pull folioorg/okapi:latest + docker run --name okapi -t -detach folioorg/okapi:latest dev + echo "OKAPI_IP=$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' okapi)" >> $GITHUB_ENV + sleep 10 + + - name: Pull all Module descriptors to local Okapi instance + if: ${{ env.PUBLISH_MOD_DESCRIPTOR == 'true' }} + uses: fjogeleit/http-request-action@master + with: + url: http://${{ env.OKAPI_IP }}:9130/_/proxy/pull/modules + method: 'POST' + contentType: 'application/json; charset=utf-8' + customHeaders: '{ "Accept": "application/json; charset=utf-8" }' + data: ${{ env.OKAPI_PULL }} + timeout: 60000 + + - name: Perform local Okapi dependency check + if: ${{ env.PUBLISH_MOD_DESCRIPTOR == 'true' }} + uses: fjogeleit/http-request-action@master + with: + url: http://${{ env.OKAPI_IP }}:9130/_/proxy/modules?preRelease=false&npmSnapshot=false + method: 'POST' + contentType: 'application/json; charset=utf-8' + customHeaders: '{ "Accept": "application/json; charset=utf-8" }' + data: ${{ steps.moduleDescriptor.outputs.content }} + + - name: Publish Jest unit test results + uses: docker://ghcr.io/enricomi/publish-unit-test-result-action:v1 + if: always() + with: + github_token: ${{ github.token }} + files: "${{ env.JEST_JUNIT_OUTPUT_DIR }}/*.xml" + check_name: Jest Unit Test Results + comment_mode: update last + comment_title: Jest Unit Test Statistics + + - name: Publish Jest coverage report + uses: actions/upload-artifact@v2 + if: always() + with: + name: jest-coverage-report + path: ${{ env.JEST_COVERAGE_REPORT_DIR }} + retention-days: 30 + + - name: Publish BigTest unit test results + uses: docker://ghcr.io/enricomi/publish-unit-test-result-action:v1 + if: always() + with: + github_token: ${{ github.token }} + files: "${{ env.BIGTEST_JUNIT_OUTPUT_DIR }}/*.xml" + check_name: BigTest Unit Test Results + comment_mode: update last + comment_title: BigTest Unit Test Statistics + + - name: Publish BigTest coverage report + uses: actions/upload-artifact@v2 + if: always() + with: + name: bigtest-coverage-report + path: ${{ env.BIGTEST_COVERAGE_REPORT_DIR }} + retention-days: 30 + + - name: Publish yarn.lock + uses: actions/upload-artifact@v2 + if: failure() + with: + name: yarn.lock + path: yarn.lock + retention-days: 5 + + - name: Set default branch as env variable + run: echo "DEFAULT_BRANCH=${{ github.event.repository.default_branch }}" >> $GITHUB_ENV + + - name: Fetch branches for SonarCloud + run: git fetch --no-tags ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} +refs/heads/${{ env.DEFAULT_BRANCH }}:refs/remotes/origin/${{ env.DEFAULT_BRANCH }} + + - name: Run SonarCloud scan + uses: sonarsource/sonarcloud-github-action@master + with: + args: > + -Dsonar.organization=folio-org + -Dsonar.projectKey=org.folio:${{ github.event.repository.name }} + -Dsonar.projectName=${{ github.event.repository.name }} + -Dsonar.sources=${{ env.SQ_ROOT_DIR }} + -Dsonar.language=js + -Dsonar.javascript.lcov.reportPaths=${{ env.SQ_LCOV_REPORT }} + -Dsonar.exclusions=${{ env.SQ_EXCLUSIONS }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + - name: Set up NPM environment for publishing + uses: actions/setup-node@v2 + with: + node-version: ${{ env.NODEJS_VERSION }} + check-latest: true + always-auth: true + + - name: Set _auth in .npmrc + run: | + npm config set @folio:registry $FOLIO_NPM_REGISTRY + npm config set _auth $NODE_AUTH_TOKEN + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Exclude some CI-generated artifacts in package + run: | + echo ".github" >> .npmignore + echo ".scannerwork" >> .npmignore + cat .npmignore + + - name: Publish NPM to FOLIO NPM registry + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Publish module descriptor to FOLIO registry + if: ${{ env.PUBLISH_MOD_DESCRIPTOR == 'true' }} + id: modDescriptorPost + uses: fjogeleit/http-request-action@master + with: + url: ${{ env.FOLIO_MD_REGISTRY }}/_/proxy/modules + method: 'POST' + contentType: 'application/json; charset=utf-8' + customHeaders: '{ "Accept": "application/json; charset=utf-8" }' + data: ${{ steps.moduleDescriptor.outputs.content }} + username: ${{ secrets.FOLIO_REGISTRY_USERNAME }} + password: ${{ secrets.FOLIO_REGISTRY_PASSWORD }} \ No newline at end of file diff --git a/.github/workflows/build-npm.yml b/.github/workflows/build-npm.yml new file mode 100644 index 00000000..ed8739ea --- /dev/null +++ b/.github/workflows/build-npm.yml @@ -0,0 +1,199 @@ +# This workflow will do a clean install of node dependencies, build the source code, +# run unit tests, perform a Sonarqube scan, and publish NPM artifacts from master/main. + +# For more information see: +# https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +# Common FOLIO configurable environment variables to set: +# - YARN_TEST_OPTIONS (options to pass to 'yarn test') +# - SQ_ROOT_DIR (root SQ directory to scan relative to top-level directory) +# - PUBLISH_MOD_DESCRIPTOR (boolean 'true' or 'false') +# - COMPILE_TRANSLATION_FILES (boolean 'true' or 'false') + + + +name: buildNPM Snapshot +on: [push, pull_request] + +jobs: + github-actions-ci: + env: + YARN_TEST_OPTIONS: '--karma.singleRun --karma.browsers ChromeDocker --karma.reporters mocha junit --coverage' + SQ_ROOT_DIR: './src' + COMPILE_TRANSLATION_FILES: 'true' + PUBLISH_MOD_DESCRIPTOR: 'true' + FOLIO_NPM_REGISTRY: 'https://repository.folio.org/repository/npm-folioci/' + FOLIO_MD_REGISTRY: 'https://folio-registry.dev.folio.org' + NODEJS_VERSION: '12' + JEST_JUNIT_OUTPUT_DIR: 'artifacts/jest-junit' + JEST_COVERAGE_REPORT_DIR: 'artifacts/coverage-jest/lcov-report/' + BIGTEST_JUNIT_OUTPUT_DIR: 'artifacts/runTest' + BIGTEST_COVERAGE_REPORT_DIR: 'artifacts/coverage/lcov-report/' + SQ_LCOV_REPORT: 'artifacts/coverage-jest/lcov.info' + SQ_EXCLUSIONS: '**/platform/alias-service.js,**/docs/**,**/node_modules/**,**/examples/**,**/artifacts/**,**/ci/**,Jenkinsfile,**/LICENSE,**/*.css,**/*.md,**/*.json,**/tests/**,**/stories/*.js,**/test/**,**/.stories.js,**/resources/bigtest/interactors/**,**/resources/bigtest/network/**,**/*-test.js,**/*.test.js,**/*-spec.js,**/karma.conf.js,**/jest.config.js' + + runs-on: ubuntu-latest + steps: + - uses: folio-org/checkout@v2 + with: + fetch-depth: 0 + + - name: Setup kernel for react native, increase watchers + run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p + - name: Use Node.js + uses: actions/setup-node@v2 + with: + node-version: ${{ env.NODEJS_VERSION }} + check-latest: true + always-auth: true + + - name: Set yarn config + run: yarn config set @folio:registry $FOLIO_NPM_REGISTRY + + - name: Set FOLIO NPM snapshot version + run: | + git clone https://github.com/folio-org/folio-tools.git + npm --no-git-tag-version version `folio-tools/github-actions-scripts/folioci_npmver.sh` + rm -rf folio-tools + env: + JOB_ID: ${{ github.run_number }} + + - name: Run yarn install + run: yarn install --ignore-scripts + + - name: Run yarn list + run: yarn list --pattern @folio + + - name: Run yarn lint + run: yarn lint + continue-on-error: true + + - name: Run yarn test + run: xvfb-run --server-args="-screen 0 1024x768x24" yarn test $YARN_TEST_OPTIONS + + - name: Run yarn formatjs-compile + if: ${{ env.COMPILE_TRANSLATION_FILES == 'true' }} + run: yarn formatjs-compile + + - name: Generate FOLIO module descriptor + if: ${{ env.PUBLISH_MOD_DESCRIPTOR == 'true' }} + run: yarn build-mod-descriptor + + - name: Print FOLIO module descriptor + if: ${{ env.PUBLISH_MOD_DESCRIPTOR == 'true' }} + run: cat module-descriptor.json + + - name: Publish Jest unit test results + uses: docker://ghcr.io/enricomi/publish-unit-test-result-action:v1 + if: always() + with: + github_token: ${{ github.token }} + files: "${{ env.JEST_JUNIT_OUTPUT_DIR }}/*.xml" + check_name: Jest Unit Test Results + comment_mode: update last + comment_title: Jest Unit Test Statistics + + - name: Publish Jest coverage report + uses: actions/upload-artifact@v2 + if: always() + with: + name: jest-coverage-report + path: ${{ env.JEST_COVERAGE_REPORT_DIR }} + retention-days: 30 + + - name: Publish BigTest unit test results + uses: docker://ghcr.io/enricomi/publish-unit-test-result-action:v1 + if: always() + with: + github_token: ${{ github.token }} + files: "${{ env.BIGTEST_JUNIT_OUTPUT_DIR }}/*.xml" + check_name: BigTest Unit Test Results + comment_mode: update last + comment_title: BigTest Unit Test Statistics + + - name: Publish BigTest coverage report + uses: actions/upload-artifact@v2 + if: always() + with: + name: bigtest-coverage-report + path: ${{ env.BIGTEST_COVERAGE_REPORT_DIR }} + retention-days: 30 + + - name: Publish yarn.lock + uses: actions/upload-artifact@v2 + if: failure() + with: + name: yarn.lock + path: yarn.lock + retention-days: 5 + + - name: Set default branch as env variable + run: echo "DEFAULT_BRANCH=${{ github.event.repository.default_branch }}" >> $GITHUB_ENV + + - name: Fetch branches for SonarCloud + run: git fetch --no-tags ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} +refs/heads/${{ env.DEFAULT_BRANCH }}:refs/remotes/origin/${{ env.DEFAULT_BRANCH }} + + - name: Run SonarCloud scan + uses: sonarsource/sonarcloud-github-action@master + with: + args: > + -Dsonar.organization=folio-org + -Dsonar.projectKey=org.folio:${{ github.event.repository.name }} + -Dsonar.projectName=${{ github.event.repository.name }} + -Dsonar.sources=${{ env.SQ_ROOT_DIR }} + -Dsonar.language=js + -Dsonar.javascript.lcov.reportPaths=${{ env.SQ_LCOV_REPORT }} + -Dsonar.exclusions=${{ env.SQ_EXCLUSIONS }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + - name: Set up NPM environment for publishing + if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }} + uses: actions/setup-node@v2 + with: + node-version: ${{ env.NODEJS_VERSION }} + check-latest: true + always-auth: true + + - name: Set _auth in .npmrc + if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }} + run: | + npm config set @folio:registry $FOLIO_NPM_REGISTRY + npm config set _auth $NODE_AUTH_TOKEN + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Exclude some CI-generated artifacts in package + if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }} + run: | + echo ".github" >> .npmignore + echo ".scannerwork" >> .npmignore + cat .npmignore + + - name: Publish NPM + if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }} + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Read module descriptor + if: ${{ env.PUBLISH_MOD_DESCRIPTOR == 'true' && github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }} + id: moduleDescriptor + uses: juliangruber/read-file-action@v1 + with: + path: ./module-descriptor.json + + - name: Publish module descriptor + if: ${{ env.PUBLISH_MOD_DESCRIPTOR == 'true' && github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }} + id: modDescriptorPost + uses: fjogeleit/http-request-action@master + with: + url: ${{ env.FOLIO_MD_REGISTRY }}/_/proxy/modules + method: 'POST' + contentType: 'application/json; charset=utf-8' + customHeaders: '{ "Accept": "application/json; charset=utf-8" }' + data: ${{ steps.moduleDescriptor.outputs.content }} + username: ${{ secrets.FOLIO_REGISTRY_USERNAME }} + password: ${{ secrets.FOLIO_REGISTRY_PASSWORD }} + diff --git a/Jenkinsfile b/Jenkinsfile.deprecated similarity index 100% rename from Jenkinsfile rename to Jenkinsfile.deprecated diff --git a/package.json b/package.json index 417dc49a..2700f23e 100644 --- a/package.json +++ b/package.json @@ -144,7 +144,9 @@ "lint": "eslint .", "test": "yarn run test:jest && yarn run test:bigtest ", "test:bigtest": "stripes test karma", - "test:jest": "jest --ci --coverage --colors" + "test:jest": "jest --ci --coverage --colors", + "build-mod-descriptor": "stripes mod descriptor --full --strict | jq '.[]' > module-descriptor.json ", + "formatjs-compile": "formatjs compile-folder --ast --format simple ./translations/ui-requests ./translations/ui-requests/compiled" }, "devDependencies": { "@babel/plugin-proposal-class-properties": "^7.13.0", @@ -158,6 +160,7 @@ "@folio/stripes-cli": "^2.0.0", "@folio/stripes-components": "^10.0.0", "@folio/stripes-core": "^8.0.0", + "@formatjs/cli": "^4.2.20", "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^11.2.5", "@testing-library/user-event": "^12.1.10",