diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..5e507274a --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,53 @@ +name: build + +on: + release: + types: [created] + push: + branches: + - "**" + +concurrency: + group: ${{ github.workflow }}-${{ startsWith(github.ref, 'refs/tags/v') && 'release' || github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/v') }} + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: read + env: + AWS_DEFAULT_REGION: eu-west-1 + PRODUCTION_CLOUDFRONT_DISTRIBUTION_ID: NOT_YET + STAGING_CLOUDFRONT_DISTRIBUTION_ID: E37K3V5Y65XQIX + REVIEW_CLOUDFRONT_DISTRIBUTION_ID: E3KUGPF02I4CJ4 + VITE_FOUNDATION_BUILD: ${{ github.repository_owner == 'microbit-foundation' }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v3 + with: + node-version: 20 + cache: 'npm' + registry-url: "https://npm.pkg.github.com" + - run: npm ci + - run: npm install --no-save @microbit-foundation/website-deploy-aws@0.6 @microbit-foundation/website-deploy-aws-config@0.9 @microbit-foundation/npm-package-versioner@2 + if: github.repository_owner == 'microbit-foundation' + env: + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - run: npx update-ci-version + - run: node ./bin/print-ci-env.cjs >> $GITHUB_ENV + - run: npm run test + - run: npm run check + - run: npx prettier --check src + - run: npm run build + - run: npx website-deploy-aws + if: github.repository_owner == 'microbit-foundation' && (env.STAGE == 'REVIEW' || success()) + env: + AWS_ACCESS_KEY_ID: ${{ secrets.WEB_DEPLOY_ML_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.WEB_DEPLOY_ML_AWS_SECRET_ACCESS_KEY }} + - run: npx invalidate-cloudfront-distribution + if: github.repository_owner == 'microbit-foundation' && (env.STAGE == 'REVIEW' || success()) + env: + AWS_ACCESS_KEY_ID: ${{ secrets.WEB_DEPLOY_ML_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.WEB_DEPLOY_ML_AWS_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index d08948308..000000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,72 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -# GitHub recommends pinning actions to a commit SHA. -# To get a newer version, you will need to update the SHA. -# You can also reference a tag or branch, but the action may change without warning. - -name: Testing deployment - -env: - APP_LOCATION: "/" # location of your client code - APP_ARTIFACT_LOCATION: "/dist" # location of client code build output - -on: - push: - branches: - - main - pull_request: - types: [opened, synchronize, reopened, closed] - branches: - - main - -permissions: - issues: write - contents: read - -jobs: - Jest: - if: false - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Run Tests - run: | - npm install - npm test - build_and_deploy: - if: false - # if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') - runs-on: ubuntu-latest - name: Build and Deploy - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - name: Branding - run: | - cp -f ./src/__viteBuildVariants__/ml-machine/windi.config.js ./windi.config.js - - name: Build And Deploy - uses: Azure/static-web-apps-deploy@1a947af9992250f3bc2e68ad0754c0b0c11566c9 - with: - azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }} - repo_token: ${{ secrets.GITHUB_TOKEN }} - action: "upload" - app_location: ${{ env.APP_LOCATION }} - app_artifact_location: ${{ env.APP_ARTIFACT_LOCATION }} - env: - VITE_TITLE: ML-Machine - - close: - if: false - # if: github.event_name == 'pull_request' && github.event.action == 'closed' - runs-on: ubuntu-latest - name: Close - steps: - - name: Close - uses: Azure/static-web-apps-deploy@1a947af9992250f3bc2e68ad0754c0b0c11566c9 - with: - azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }} - action: "close" diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml deleted file mode 100644 index abd39d097..000000000 --- a/.github/workflows/production.yml +++ /dev/null @@ -1,71 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -# GitHub recommends pinning actions to a commit SHA. -# To get a newer version, you will need to update the SHA. -# You can also reference a tag or branch, but the action may change without warning. - -name: Production deployment - -env: - APP_LOCATION: "/" # location of your client code - APP_ARTIFACT_LOCATION: "/dist" # location of client code build output - -on: - push: - branches: - - production - pull_request: - types: [opened, synchronize, reopened, closed] - branches: - - production - -permissions: - issues: write - contents: read - -jobs: - Jest: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Run Tests - run: | - npm install - npm test - build_and_deploy: - if: false - # if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') - runs-on: ubuntu-latest - name: Build and Deploy - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - name: Branding - run: | - cp -f ./src/__viteBuildVariants__/ml-machine/windi.config.js ./windi.config.js - - name: Build And Deploy - uses: Azure/static-web-apps-deploy@1a947af9992250f3bc2e68ad0754c0b0c11566c9 - with: - azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_PRODUCTION_TOKEN }} - repo_token: ${{ secrets.GITHUB_TOKEN }} - action: "upload" - app_location: ${{ env.APP_LOCATION }} - app_artifact_location: ${{ env.APP_ARTIFACT_LOCATION }} - env: - VITE_TITLE: ML-Machine - - close: - if: false - # if: github.event_name == 'pull_request' && github.event.action == 'closed' - runs-on: ubuntu-latest - name: Close - steps: - - name: Close - uses: Azure/static-web-apps-deploy@1a947af9992250f3bc2e68ad0754c0b0c11566c9 - with: - azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_PRODUCTION_TOKEN }} - action: "close" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index d6ab866d4..000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Run tests & build - -on: - push: - branches: '*' - pull_request: - branches: '*' - -jobs: - test-and-build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 - with: - node-version: 20 - cache: 'npm' - - run: npm install - - run: npm run test - - run: npm run check - - run: npx prettier --check src - - run: npm run build diff --git a/bin/print-ci-env.cjs b/bin/print-ci-env.cjs new file mode 100644 index 000000000..2f33d7755 --- /dev/null +++ b/bin/print-ci-env.cjs @@ -0,0 +1,23 @@ +#!/usr/bin/env node + +const ref = process.env.GITHUB_REF; +let stage; +if (ref === 'refs/heads/main') { + stage = 'STAGING'; +} else if (ref.startsWith('refs/tags/v')) { + stage = 'PRODUCTION'; +} else { + stage = 'REVIEW'; +} + +process.env.STAGE = stage; +// STAGE must be defined before this is imported +const { bucketName, bucketPrefix } = require('../deployment.cjs'); +const baseUrl = !bucketPrefix ? '/' : `/${bucketPrefix}/`; +const fullUrl = `https://${bucketName}${baseUrl}`; + +console.log(`STAGE=${stage}`); +console.log(`VITE_STAGE=${stage}`); +console.log(`BASE_URL=${baseUrl}`); +// This can be used for og:url and similar. Not quite right for review domain but we don't really care. +console.log(`VITE_FULL_URL=${fullUrl}`); diff --git a/deployment.cjs b/deployment.cjs new file mode 100644 index 000000000..342be4a3b --- /dev/null +++ b/deployment.cjs @@ -0,0 +1,50 @@ +const { + createDeploymentDetailsFromOptions, +} = require('@microbit-foundation/website-deploy-aws-config'); + +const { s3Config } = createDeploymentDetailsFromOptions({ + production: { + bucket: 'ml.microbit.org', + mode: 'root', + allowPrerelease: false, + }, + staging: { + bucket: 'stage-ml.microbit.org', + }, + review: { + bucket: 'review-ml.microbit.org', + mode: 'branch-prefix', + }, +}); + +module.exports = { + deploymentDir: './dist', + ...s3Config, + region: 'eu-west-1', + removeNonexistentObjects: true, + enableS3StaticWebsiteHosting: true, + errorDocumentKey: 'index.html', + redirects: [], + params: { + '**/**.html': { + CacheControl: 'public, max-age=0, must-revalidate', + }, + '**/assets/**': { CacheControl: 'public, max-age=31536000, immutable' }, + // There's lots in public/ that we'd ideally use the bundler for to improve caching + 'css/**': { + CacheControl: 'public, max-age=0, must-revalidate', + }, + 'firmware/**': { + CacheControl: 'public, max-age=0, must-revalidate', + }, + 'imgs/**': { + CacheControl: 'public, max-age=0, must-revalidate', + }, + 'sounds/**': { + CacheControl: 'public, max-age=0, must-revalidate', + }, + 'webfonts/**': { + CacheControl: 'public, max-age=0, must-revalidate', + }, + }, +}; diff --git a/index.html b/index.html index 0aba02bf2..e97246757 100644 --- a/index.html +++ b/index.html @@ -12,8 +12,8 @@
{$t('connectMB.bluetooth.connecting')}
- +