diff --git a/.github/workflows/continuous-delivery.yml b/.github/workflows/continuous-delivery.yml index aceec11e..86a8446d 100644 --- a/.github/workflows/continuous-delivery.yml +++ b/.github/workflows/continuous-delivery.yml @@ -1,13 +1,103 @@ -name: VSF Continuous Delivery +name: Release on: - workflow_dispatch: - push: - branches: - - main - + workflow_call: + secrets: + NPM_USER: + description: "repository NPM_USER secret passed on" + required: false + NPM_PASS: + description: "repository NPM_PASS secret passed on" + required: false + NPM_EMAIL: + description: "repository NPM_EMAIL secret passed on" + required: false + inputs: + enterprise: + description: "Flag to use enterprise registry" + type: boolean + required: false + default: false + +defaults: + run: + shell: bash + +env: + GCP_PROJECT_ID: 81559754996 + GCP_PROJECT_NAME: sf-artifacts-prod + jobs: - release-packages: - name: "Release NPM Packages" - uses: vuestorefront/integrations-github-workflows/.github/workflows/continuous-delivery.yml@develop - secrets: inherit \ No newline at end of file + changelog: + name: Changelog PR or Release + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + pull-requests: write + + steps: + - uses: actions/checkout@v3 + + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version-file: '.node-version' + + - if: ${{ inputs.enterprise }} + id: auth + name: Authenticate to Google Cloud + uses: google-github-actions/auth@v1 + with: + workload_identity_provider: projects/${{ env.GCP_PROJECT_ID }}/locations/global/workloadIdentityPools/sf-artifacts-prod-01/providers/sf-artifacts-prod-01 + service_account: workload-identity-federation@sf-artifacts-prod.iam.gserviceaccount.com + token_format: access_token + # The credentials file is created in repo root as an untracked file in Git + # Changesets commits all files in the repo root when creating an automated bot PR + # This causes plaintext credentials to show up in automated PRs + # So let's not create this file at all + create_credentials_file: false + + - if: ${{ inputs.enterprise }} + name: Set Artifact Registry & Verdaccio tokens + run: | + # set token for Artifact Registry + npm config set //europe-west1-npm.pkg.dev/${{ env.GCP_PROJECT_NAME }}/npm/:_authToken=${{ steps.auth.outputs.access_token }} + # set token for Verdaccio + npx npm-cli-login -u ${{ secrets.NPM_USER }} -p ${{ secrets.NPM_PASS }} -e ${{ secrets.NPM_EMAIL }} -r https://registrynpm.storefrontcloud.io + + - if: ${{ !inputs.enterprise }} + run: npm config set //registry.npmjs.org/:_authToken=${{ secrets.NPM_RELEASE_TOKEN }} + + - name: Install dependencies + run: HUSKY=0 yarn --frozen-lockfile + + - name: Create Release Pull Request or Publish + id: changesets + uses: changesets/action@v1 + with: + commit: "ci: release" + title: "ci: release" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - if: ${{ (inputs.enterprise == true) && (steps.changesets.outputs.hasChangesets == 'false') }} + name: Publish in Artifact Registry + run: | + yarn build && \ + npm config --location project set @vsf-enterprise:registry=https://europe-west1-npm.pkg.dev/${{ env.GCP_PROJECT_NAME }}/npm/ && \ + yarn changeset publish + + # Remove this step once Verdaccio is removed by the Cloud Team for good. + # It's possible to use `continue-on-error: true` here for max futureproofing, + # but this also makes publishing failures show as successful despite errors, so I didn't do that + - if: ${{ (inputs.enterprise == true) && (steps.changesets.outputs.hasChangesets == 'false') }} + name: Publish in Verdaccio + run: | + npm config --location project set @vsf-enterprise:registry=https://registrynpm.storefrontcloud.io/ && \ + yarn changeset publish + + + - if: ${{ (inputs.enterprise == false) && (steps.changesets.outputs.hasChangesets == 'false') }} + name: Publish + run: yarn build && yarn changeset publish \ No newline at end of file diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index c63303bf..376c22e0 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -1,40 +1,111 @@ -name: VSF Continuous Integration +name: Continous Integration on: - pull_request: - types: ['opened', 'edited', 'reopened', 'synchronize'] + workflow_call: + inputs: + enterprise: + description: "Flag to use enterprise registry" + type: boolean + required: false + default: false -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true + node_version: + description: "Node versions to test" + type: string + required: false + default: "['16']" + +defaults: + run: + shell: bash + +env: + GCP_PROJECT_ID: 81559754996 + GCP_PROJECT_NAME: sf-artifacts-prod jobs: - continous-integration: - name: 'Continuous Integration' - uses: vuestorefront/integrations-github-workflows/.github/workflows/continuous-integration.yml@main - secrets: inherit - with: - enterprise: false - node_version: '["16", "18"]' - - sonarcloud-api-client: - name: 'SonarCloud API Client' - needs: [continous-integration] - uses: vuestorefront/integrations-github-workflows/.github/workflows/sonarcloud.yml@develop - secrets: - SONARCLOUD_TOKEN: ${{ secrets.SONARCLOUD_TOKEN_API_CLIENT }} - with: - project_key: 'vuestorefront_magento2_api-client' - package_name: 'api-client' - exclusions: '*.config.js,src/index.ts,src/api-extractor-data.ts,**/types/**' - - sonarcloud-sdk: - name: 'SonarCloud SDK' - needs: [continous-integration] - uses: vuestorefront/integrations-github-workflows/.github/workflows/sonarcloud.yml@develop - secrets: - SONARCLOUD_TOKEN: ${{ secrets.SONARCLOUD_TOKEN_SDK }} - with: - project_key: 'vuestorefront_magento2_sdk' - package_name: 'sdk' - exclusions: '*.config.js,*.config.*.ts,src/index.ts,src/connector.ts,src/api-extractor-data.ts,**/types/**,' \ No newline at end of file + run-ci: + name: Run CI + runs-on: ubuntu-latest + strategy: + matrix: + node_version: ${{ fromJson(inputs.node_version) }} + permissions: + contents: read + id-token: write + steps: + - name: Expose github environment as shell variables + env: + SECRETS_CONTEXT: ${{ toJson(secrets) }} + VARS_CONTEXT: ${{ toJson(vars) }} + run: | + # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable + # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings + EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) + to_envs() { jq -r "to_entries[] | \"\(.key)<<$EOF\n\(.value)\n$EOF\n\""; } + echo "$SECRETS_CONTEXT" | to_envs >> $GITHUB_ENV + - name: Checkout code ๐Ÿ›Ž๏ธ + uses: actions/checkout@v3 + + - name: Setup node ๐Ÿ—๏ธ + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node_version }} + + - name: Get cache ๐Ÿ—„๏ธ + id: cache + uses: actions/cache@v3 + with: + path: '**/node_modules' + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} + + # IN-3457 + - id: auth + name: Authenticate to Google Cloud + if: ${{ inputs.enterprise }} + uses: google-github-actions/auth@v1 + with: + workload_identity_provider: projects/${{ env.GCP_PROJECT_ID }}/locations/global/workloadIdentityPools/sf-artifacts-prod-01/providers/sf-artifacts-prod-01 + service_account: workload-identity-federation@sf-artifacts-prod.iam.gserviceaccount.com + token_format: access_token + create_credentials_file: false + + - if: ${{ inputs.enterprise }} + run: | + npm config set //europe-west1-npm.pkg.dev/${{ env.GCP_PROJECT_NAME }}/npm/:_authToken=${{ steps.auth.outputs.access_token }} + npm config set //registrynpm.storefrontcloud.io/:_authToken=${{ secrets.NPM_DEFAULT_ENTERPRISE_TOKEN }} + + - if: ${{ !inputs.enterprise }} + run: npm config set //registry.npmjs.org/:_authToken=${{ secrets.NPM_RELEASE_TOKEN }} + + - name: Install dependencies + shell: bash + if: steps.cache.outputs.cache-hit != true + run: HUSKY=0 yarn --frozen-lockfile + + - name: Detect circular dependencies ๐Ÿ”„ + uses: vuestorefront/engineering-toolkit/github-actions/circular-dependencies@main + with: + filesPath: 'packages/**/*.{ts,vue}' + + - name: Check licenses ๐Ÿงช + uses: vuestorefront/engineering-toolkit/github-actions/check-licenses@main + with: + projectPath: ${{ github.workspace }} + + - name: Build project + run: yarn build + + - name: Run tests + run: yarn test + + - name: Upload test coverage + uses: actions/upload-artifact@v3 + with: + name: coverage-${{ runner.os }}-${{ github.event.pull_request.head.sha }} + path: | + coverage + packages/**/coverage + + - name: Lint project + run: yarn lint \ No newline at end of file