diff --git a/.github/workflows/build-development.yml b/.github/workflows/build-development.yml index 4d009beb46..9b29423799 100644 --- a/.github/workflows/build-development.yml +++ b/.github/workflows/build-development.yml @@ -9,76 +9,65 @@ jobs: name: Build and deploy sourceacademy.org runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - name: Use Node.js - uses: actions/setup-node@v2-beta - with: - node-version: '16' - - name: Setup Sentry CLI - run: | - curl -sL https://sentry.io/get-cli/ | INSTALL_DIR=. bash - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT - - id: get-time - run: echo "time=$(date -Iseconds)" >> $GITHUB_OUTPUT - - uses: actions/cache@v2 - id: yarn-cache - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: 1-${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - 1-${{ runner.os }}-yarn- - - uses: actions/cache@v2 - id: build-cache - with: - path: node_modules/.cache - key: 1-${{ runner.os }}-build-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - 1-${{ runner.os }}-build- - - name: yarn install and build - run: | - yarn install - yarn run build - env: - REACT_APP_URL_SHORTENER_SIGNATURE: ${{ secrets.REACT_APP_URL_SHORTENER_SIGNATURE }} - REACT_APP_URL_SHORTENER_BASE: ${{ secrets.REACT_APP_URL_SHORTENER_BASE }} - REACT_APP_SENTRY_DSN: ${{ secrets.REACT_APP_SENTRY_DSN }} - REACT_APP_GOOGLE_CLIENT_ID: ${{ secrets.REACT_APP_GOOGLE_CLIENT_ID }} - REACT_APP_GOOGLE_API_KEY: ${{ secrets.REACT_APP_GOOGLE_API_KEY }} - REACT_APP_GOOGLE_APP_ID: ${{ secrets.REACT_APP_GOOGLE_APP_ID }} - REACT_APP_PLAYGROUND_ONLY: "TRUE" - REACT_APP_ENABLE_GITHUB_ASSESSMENTS: "TRUE" - REACT_APP_VERSION: ${{ format('{0}-{1}', github.sha, steps.get-time.outputs.time) }} - REACT_APP_ENVIRONMENT: "pages" - REACT_APP_MODULE_BACKEND_URL: https://source-academy.github.io/modules - REACT_APP_SHAREDB_BACKEND_URL: ${{ secrets.REACT_APP_SHAREDB_BACKEND_URL }} - PUBLIC_URL: "https://sourceacademy.org" - REACT_APP_GITHUB_OAUTH_PROXY_URL: ${{ secrets.REACT_APP_GITHUB_OAUTH_PROXY_URL }} - REACT_APP_GITHUB_CLIENT_ID: ${{ secrets.REACT_APP_GITHUB_CLIENT_ID }} - - name: Create Sentry release - working-directory: build - run: | - SENTRY_RELEASE="cadet-frontend@$REACT_APP_VERSION" - "$GITHUB_WORKSPACE/sentry-cli" releases new -p "$SENTRY_PROJECT" "$SENTRY_RELEASE" - "$GITHUB_WORKSPACE/sentry-cli" releases set-commits --auto "$SENTRY_RELEASE" - "$GITHUB_WORKSPACE/sentry-cli" releases files "$SENTRY_RELEASE" upload-sourcemaps --url-prefix '~/static/js' --rewrite static/js - "$GITHUB_WORKSPACE/sentry-cli" releases finalize "$SENTRY_RELEASE" - "$GITHUB_WORKSPACE/sentry-cli" releases deploys "$SENTRY_RELEASE" new -e pages - env: - SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} - SENTRY_ORG: sourceacademy - SENTRY_PROJECT: cadet-frontend - REACT_APP_VERSION: ${{ format('{0}-{1}', github.sha, steps.get-time.outputs.time) }} - - name: Remove sourcemaps - working-directory: build - run: | - find -name '*.map' -print -delete - - name: Deploy - uses: peaceiris/actions-gh-pages@v3 - with: - external_repository: source-academy/sourceacademy.org - deploy_key: ${{ secrets.DEPLOY_PRIVATE_KEY }} - publish_dir: ./build - publish_branch: master - force_orphan: true + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install dependencies (apt) + run: | + sudo apt-get install -y --no-install-recommends \ + libxi-dev libgl1-mesa-dev + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: yarn + - name: Setup Sentry CLI + run: | + curl -sL https://sentry.io/get-cli/ | INSTALL_DIR=. bash + - id: get-time + run: echo "time=$(date -Iseconds)" >> $GITHUB_OUTPUT + - name: yarn install and build + run: | + yarn install --frozen-lockfile + yarn run build + env: + REACT_APP_URL_SHORTENER_SIGNATURE: ${{ secrets.REACT_APP_URL_SHORTENER_SIGNATURE }} + REACT_APP_URL_SHORTENER_BASE: ${{ secrets.REACT_APP_URL_SHORTENER_BASE }} + REACT_APP_SENTRY_DSN: ${{ secrets.REACT_APP_SENTRY_DSN }} + REACT_APP_GOOGLE_CLIENT_ID: ${{ secrets.REACT_APP_GOOGLE_CLIENT_ID }} + REACT_APP_GOOGLE_API_KEY: ${{ secrets.REACT_APP_GOOGLE_API_KEY }} + REACT_APP_GOOGLE_APP_ID: ${{ secrets.REACT_APP_GOOGLE_APP_ID }} + REACT_APP_PLAYGROUND_ONLY: 'TRUE' + REACT_APP_ENABLE_GITHUB_ASSESSMENTS: 'TRUE' + REACT_APP_VERSION: ${{ format('{0}-{1}', github.sha, steps.get-time.outputs.time) }} + REACT_APP_ENVIRONMENT: 'pages' + REACT_APP_MODULE_BACKEND_URL: https://source-academy.github.io/modules + REACT_APP_SHAREDB_BACKEND_URL: ${{ secrets.REACT_APP_SHAREDB_BACKEND_URL }} + PUBLIC_URL: 'https://sourceacademy.org' + REACT_APP_GITHUB_OAUTH_PROXY_URL: ${{ secrets.REACT_APP_GITHUB_OAUTH_PROXY_URL }} + REACT_APP_GITHUB_CLIENT_ID: ${{ secrets.REACT_APP_GITHUB_CLIENT_ID }} + - name: Create Sentry release + working-directory: build + run: | + SENTRY_RELEASE="cadet-frontend@$REACT_APP_VERSION" + "$GITHUB_WORKSPACE/sentry-cli" releases new -p "$SENTRY_PROJECT" "$SENTRY_RELEASE" + "$GITHUB_WORKSPACE/sentry-cli" releases set-commits --auto "$SENTRY_RELEASE" + "$GITHUB_WORKSPACE/sentry-cli" releases files "$SENTRY_RELEASE" upload-sourcemaps --url-prefix '~/static/js' --rewrite static/js + "$GITHUB_WORKSPACE/sentry-cli" releases finalize "$SENTRY_RELEASE" + "$GITHUB_WORKSPACE/sentry-cli" releases deploys "$SENTRY_RELEASE" new -e pages + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: sourceacademy + SENTRY_PROJECT: cadet-frontend + REACT_APP_VERSION: ${{ format('{0}-{1}', github.sha, steps.get-time.outputs.time) }} + - name: Remove sourcemaps + working-directory: build + run: | + find -name '*.map' -print -delete + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + external_repository: source-academy/sourceacademy.org + deploy_key: ${{ secrets.DEPLOY_PRIVATE_KEY }} + publish_dir: ./build + publish_branch: master + force_orphan: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4ebae59bdb..303985ca98 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,11 +19,15 @@ jobs: commands: [tsc, 'format:ci', eslint, build, test, test-coveralls] steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + - name: Install dependencies (apt) + run: | + sudo apt-get install -y --no-install-recommends \ + libxi-dev libgl1-mesa-dev - name: Setup node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: 16 + node-version: 20 cache: yarn - name: Install dependencies run: yarn install --frozen-lockfile diff --git a/.node-version b/.node-version new file mode 100644 index 0000000000..43bff1f8cf --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +20.9.0 \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..6c32d7e20c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,40 @@ +# Contributing Guide + +Refer to our issue tracker and contribute to any open issues you are able to spot there. If you have any new issues, please do post there as well. We welcome any form of contribution and are open to any new ideas you may have for the project! + +To start contributing, create a fork from our repo and send a PR. Refer to [this article](https://help.github.com/en/articles/fork-a-repo) for more information. + +## Application Structure + +1. `assets` contains static assets. +1. `commons` contains components or other code common to more than one page. +1. `features` contains action creators, reducers and type declarations for specific functions. +1. `pages` contains pages and components used only in one page; its layout should mirror the actual routes. +1. `styles` contains all SCSS styles. + +## Testing + +The frontend comes with an extensive test suite. To run the tests after you made your modifications, run +`yarn test`. Regression tests are run automatically when you want to push changes to this repository. +The regression tests are generated using `jest` and stored as snapshots in `src/\_\_tests\_\_`. After modifying the frontend, carefully inspect any failing regression tests reported in red in the command line. If you are convinced that the regression tests and not your changes are at fault, you can update the regression tests by running: + +```bash +yarn test --updateSnapshot +``` + +## Manually testing the frontend + +Before pushing to Github, ensure that your code is formatted and your tests are passing. These two commands should help with that: + +- `yarn run format` : formats your code +- `yarn run test`: runs the tests and prints the output + +## Running your own js-slang + +See [js-slang README](https://github.com/source-academy/js-slang#using-your-js-slang-in-local-source-academy) for instructions how to run your own js-slang in the frontend. + +## TypeScript Coding Conventions + +We reference [this guide](https://github.com/piotrwitek/react-redux-typescript-guide). + +See also the [this standard in the wiki](https://github.com/source-academy/frontend/wiki/Coding-Standard). diff --git a/README.md b/README.md index 3201f87f8a..226cd9a10f 100644 --- a/README.md +++ b/README.md @@ -18,29 +18,34 @@ The Source Academy () is an immersive online experie ## Getting Started -### Installation of Source Academy (latest version [available in GitHub Pages](https://source-academy.github.io/)) +### Installation of [Source Academy](https://source-academy.github.io/) -1. Install the current LTS version of Node.js. The current version (usually the version one greater than the current LTS) may also work, but if you encounter issues, use the current or lower LTS version. (Known working version of node: v16.16.0) -2. Clone this repository and navigate to it using "cd" in your command line or shell tool. -3. Run `yarn install` to install dependencies. - - If you are on Ubuntu and encounter the error message: `No such file or directory: 'install'`, you might be running the incorrect "yarn" from the cmdtest testing suite instead of the JavaScript package manager of the same name. Refer to this [StackOverflow post](https://stackoverflow.com/questions/46013544/yarn-install-command-error-no-such-file-or-directory-install). - - If you are on the new M1 or M2 Mac chips, and encounter an error while installing `canvas`, refer to [this documentation](https://github.com/Automattic/node-canvas/wiki/Installation:-Mac-OS-X#homebrew) to install the requisite dependencies first. +1. Install the version of Node.js as specified in the `.node-version` file +1. Install Python (known working versions: `2.7`, `3.8`, `3.9`, `3.10`) – **Note: Python `3.11` does not work** -4. Run `yarn run start` to start the server at `localhost:8000`. **It might take a couple of minutes for the server to start.** -5. Point your browser to `http://localhost:8000` to see your local Source Academy. +1. Clone this repository and navigate to it using your command line + +1. Run `yarn install` to install dependencies. + + - If you are on Ubuntu and encounter the error message: `No such file or directory: 'install'`, you might be running the incorrect "yarn" from the cmdtest testing suite instead of the JavaScript package manager of the same name. Refer to this [StackOverflow post](https://stackoverflow.com/questions/46013544/yarn-install-command-error-no-such-file-or-directory-install). + - If you are on the new M1 or M2 Mac chips, and encounter an error while installing `canvas`, refer to [this documentation](https://github.com/Automattic/node-canvas/wiki/Installation:-Mac-OS-X#homebrew) to install the requisite dependencies first. + +1. Run `yarn run start` to start the server at `localhost:8000`. **It might take a couple of minutes for the server to start.** + +1. Point your browser to `http://localhost:8000` to see your local Source Academy. In this edition, you will only see the Playground with all its tools, but no login options or homework submission features. If you wish to set up the GitHub or Google Drive integrations, copy the `.env.example` file as `.env` and refer to [_Setting up your environment_](#setting-up-your-environment) below for the relevant configuration options. -### Installation of Source Academy @ NUS (access [latest production version here](https://sourceacademy.nus.edu.sg)) +### Installation of [Source Academy @ NUS](https://sourceacademy.nus.edu.sg) + +1. Repeat steps 1-4 above +1. Copy the `.env.example` file as `.env` and set the necessary variables (refer below for more information) +1. Run `yarn run start` to start the server at `localhost:8000` -1. Install the current LTS version of Node.js. The current version (usually the version one greater than the current LTS) may also work, but if you encounter issues, use the current LTS. -2. Clone this repository and navigate to it using "cd" in your command line or shell tool. -3. Run `yarn install` to install dependencies. -4. Copy the `.env.example` file as `.env` and set the necessary variables (refer below for more information) -5. Run `yarn run start` to start the server at `localhost:8000`. **It might take a couple of minutes for the server to start.** +**Note: It might take a couple of minutes for the server to start the first time.** ### Setting up your environment @@ -88,39 +93,6 @@ See [here](https://github.com/source-academy/frontend/wiki/Google-Drive-Persiste 1. `REACT_APP_ENABLE_GITHUB_ASSESSMENTS`: Whether to enable the GitHub Assessments feature. Off by default. 1. `REACT_APP_SHOW_RESEARCH_PROMPT`: Whether to show the educational research consent prompt to users. This is mainly for instructors using their own deployment of Source Academy @ NUS to disable this prompt. -## Development - -### Running the tests - -Before pushing to Github, ensure that your code is formatted and your tests are passing. These two commands should help with that: - -- `yarn run format` : formats your code -- `yarn run test`: runs the tests and prints the output - -### Running your own js-slang - -See [js-slang README](https://github.com/source-academy/js-slang#using-your-js-slang-in-local-source-academy) for instructions how to run your own js-slang in the frontend. - -### Contribution Guidelines - -Refer to our issue tracker and contribute to any open issues you are able to spot there. If you have any new issues, please do post there as well. We welcome any form of contribution and are open to any new ideas you may have for the project! - -To start contributing, create a fork from our repo and send a PR. Refer to [this article](https://help.github.com/en/articles/fork-a-repo) for more information. - -### Application Structure - -1. `assets` contains static assets. -1. `commons` contains components or other code common to more than one page. -1. `features` contains action creators, reducers and type declarations for specific functions. -1. `pages` contains pages and components used only in one page; its layout should mirror the actual routes. -1. `styles` contains all SCSS styles. - -### TypeScript Coding Conventions - -We reference [this guide](https://github.com/piotrwitek/react-redux-typescript-guide). - -See also the [this standard in the wiki](https://github.com/source-academy/frontend/wiki/Coding-Standard). - ## Projects For more info on specific frontend projects, please consult [our wiki](https://github.com/source-academy/frontend/wiki). @@ -136,19 +108,6 @@ There are a few additional environment variables that are used when building and 1. `REACT_APP_CADET_LOGGER`: Log server URL. To test with cadet-logger on localhost, set it to `http://localhost:8001/assessment-logger`. 1. `REACT_APP_CADET_LOGGER_INTERVAL`: The interval (in ms) that the frontend should upload logs. -## Testing - -The frontend comes with an extensive test suite. To run the tests after you made your modifications, run -`yarn test`. Regression tests are run automatically when you want to push changes to this repository. -The regression tests are generated using `jest` and stored as snapshots in `src/\_\_tests\_\_`. After modifying the frontend, carefully inspect any failing regression tests reported in red in the command line. If you are convinced that the regression tests and not your changes are at fault, you can update the regression tests by running: - -``` {.} -$ yarn test --updateSnapshot -``` - -and then typing `a` to update all snapshots. -(if you run this on a macBook with ARM chip, you may run into errors; try to do this on a computer with x86 chip instead) - ## License [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) diff --git a/package.json b/package.json index f4921ee477..d09d618e9d 100644 --- a/package.json +++ b/package.json @@ -150,6 +150,9 @@ "url": "^0.11.1", "webpack-bundle-analyzer": "^4.9.0" }, + "resolutions": { + "**/gl": "^6.0.2" + }, "browserslist": { "production": [ "Firefox ESR", diff --git a/yarn.lock b/yarn.lock index d4912351ff..cb877267dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6190,6 +6190,11 @@ expect@^29.0.0: jest-message-util "^29.5.0" jest-util "^29.5.0" +exponential-backoff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" + integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== + express@^4.17.3: version "4.18.2" resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" @@ -6668,17 +6673,17 @@ gl-wiretap@^0.6.2: resolved "https://registry.yarnpkg.com/gl-wiretap/-/gl-wiretap-0.6.2.tgz#e4aa19622831088fbaa7e5a18d01768f7a3fb07c" integrity sha512-fxy1XGiPkfzK+T3XKDbY7yaqMBmozCGvAFyTwaZA3imeZH83w7Hr3r3bYlMRWIyzMI/lDUvUMM/92LE2OwqFyQ== -gl@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/gl/-/gl-5.0.3.tgz#a10f37c50e48954348cc3e790b83313049bdbe1c" - integrity sha512-toWmb3Rgli5Wl9ygjZeglFBVLDYMOomy+rXlVZVDCoIRV+6mQE5nY4NgQgokYIc5oQzc1pvWY9lQJ0hGn61ZUg== +gl@^5.0.3, gl@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/gl/-/gl-6.0.2.tgz#685579732a19075e3acf4684edb1270278e551c7" + integrity sha512-yBbfpChOtFvg5D+KtMaBFvj6yt3vUnheNAH+UrQH2TfDB8kr0tERdL0Tjhe0W7xJ6jR6ftQBluTZR9jXUnKe8g== dependencies: bindings "^1.5.0" bit-twiddle "^1.0.2" glsl-tokenizer "^2.1.5" - nan "^2.16.0" - node-abi "^3.22.0" - node-gyp "^9.0.0" + nan "^2.17.0" + node-abi "^3.26.0" + node-gyp "^9.2.0" prebuild-install "^7.1.1" glob-parent@^5.1.2, glob-parent@~5.1.2: @@ -9261,7 +9266,7 @@ multicast-dns@^7.2.5: dns-packet "^5.2.2" thunky "^1.0.2" -nan@^2.16.0, nan@^2.17.0: +nan@^2.17.0: version "2.17.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== @@ -9309,7 +9314,14 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -node-abi@^3.22.0, node-abi@^3.3.0: +node-abi@^3.26.0: + version "3.51.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.51.0.tgz#970bf595ef5a26a271307f8a4befa02823d4e87d" + integrity sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA== + dependencies: + semver "^7.3.5" + +node-abi@^3.3.0: version "3.33.0" resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.33.0.tgz#8b23a0cec84e1c5f5411836de6a9b84bccf26e7f" integrity sha512-7GGVawqyHF4pfd0YFybhv/eM9JwTtPqx0mAanQ146O3FlSh3pA24zf9IRQTOsfTSqXTNzPSP5iagAJ94jjuVog== @@ -9333,12 +9345,13 @@ node-getopt@^0.3, node-getopt@^0.3.2: resolved "https://registry.yarnpkg.com/node-getopt/-/node-getopt-0.3.2.tgz#57507cd22f6f69650aa99252304a842f1224e44c" integrity sha512-yqkmYrMbK1wPrfz7mgeYvA4tBperLg9FQ4S3Sau3nSAkpOA0x0zC8nQ1siBwozy1f4SE8vq2n1WKv99r+PCa1Q== -node-gyp@^9.0.0: - version "9.3.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.3.1.tgz#1e19f5f290afcc9c46973d68700cbd21a96192e4" - integrity sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg== +node-gyp@^9.2.0: + version "9.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" + integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== dependencies: env-paths "^2.2.0" + exponential-backoff "^3.1.1" glob "^7.1.4" graceful-fs "^4.2.6" make-fetch-happen "^10.0.3"