diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 79a332a..0000000 --- a/.eslintrc +++ /dev/null @@ -1,48 +0,0 @@ -{ - "extends": "standard", - "globals": { - "org": true, - "CryptoJS": true, - "_": true, - "$": true, - "angular": true, - "ecEditor": true, - "EkTelemetry": true, - "EkstepEditor": true, - "EkstepEditorAPI": true, - "Class": true, - "UUID": true, - "WebFontConfig": true, - "TextWYSIWYG": true, - "ManifestGenerator": true, - "WebFont": true, - "fabric": true, - "ServiceConstants": true, - "async": true, - "Fingerprint2": true, - "describe": true, - "jasmine": true, - "afterAll": true, - "beforeAll": true, - "it": true, - "spyOn": true, - "expect": true, - "xit": true, - "EventBus": true, - "beforeEach": true, - "canvas": true, - "Plugin": true, - "createjs": true, - "p": true, - "basePlugin": true, - "Mousetrap": true, - "afterEach": true, - "location": true, - "X2JS": true - }, - "rules": { - "indent": [2, "tab"], - "no-tabs": 0, - "no-throw-literal": "error" - } -} \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..9310e2c --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,53 @@ +// this plugin is used to make all rules default to warnings +require('eslint-plugin-only-warn'); + +module.exports = { + extends: 'standard', + plugins: ['only-warn'], // makes all rules default to warnings + ignorePatterns: ['gulpfile.js', 'webpack.config.js', 'app/bower_components/**'], + globals: { + org: true, + CryptoJS: true, + _: true, + $: true, + angular: true, + ecEditor: true, + EkTelemetry: true, + EkstepEditor: true, + EkstepEditorAPI: true, + Class: true, + UUID: true, + WebFontConfig: true, + TextWYSIWYG: true, + ManifestGenerator: true, + WebFont: true, + fabric: true, + ServiceConstants: true, + async: true, + Fingerprint2: true, + describe: true, + jasmine: true, + afterAll: true, + beforeAll: true, + it: true, + spyOn: true, + expect: true, + xit: true, + EventBus: true, + beforeEach: true, + canvas: true, + Plugin: true, + createjs: true, + p: true, + basePlugin: true, + Mousetrap: true, + afterEach: true, + location: true, + X2JS: true + }, + rules: { + indent: [2, 'tab'], + 'no-tabs': 0, + 'no-throw-literal': 'error', + } +} \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..95662cd --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,109 @@ +name: Publish Sunbird-generic-editor to blob + +on: + push: + tags: + - '*' + +env: + NODE_VERSION: 10.24.1 + version_number: ${{ github.ref_name }} + build_number: ${{ github.run_number }} + CLOUD_PROVIDER: ${{ vars.CLOUD_PROVIDER }} + GCP_BUCKET: ${{ vars.GCP_BUCKET }} + AZURE_CONTAINER: ${{ vars.AZURE_CONTAINER }} + +jobs: + publish: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Cache node modules + uses: actions/cache@v3 + with: + path: node_modules + key: ${{ runner.os }}-node-${{ hashFiles('package.json') }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + registry-url: 'https://registry.npmjs.org/' + + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y build-essential libpng-dev + + - name: Clone content plugins + run: | + git clone https://github.com/sanketika-labs/sunbird-content-plugins.git plugins -b ${{ github.ref_name }} + + - name: Install global dependencies + run: | + npm install -g bower@1.8.0 grunt-cli@1.2.0 gulp@3.9.1 + + - name: Install dependencies + run: npm install --legacy-peer-deps + env: + PHANTOMJS_PLATFORM: linux + PHANTOMJS_ARCH: x64 + TMPDIR: /tmp + + - name: Install bower dependencies + working-directory: app + run: | + bower cache clean --allow-root + bower install --force --allow-root + + - name: Build and package + run: | + npm install gulp-gzip --save-dev + npm run build-npm-pkg + + - name: Setup Google Cloud SDK + if: env.CLOUD_PROVIDER == 'gcp' + uses: google-github-actions/setup-gcloud@v1 + with: + install_components: 'gsutil' + + - name: Authenticate and Upload to Google Cloud Storage + if: env.CLOUD_PROVIDER == 'gcp' + run: | + echo "${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}" | base64 -d > /tmp/service-account-key.json + gcloud auth activate-service-account --key-file=/tmp/service-account-key.json + gsutil -m cp -r generic-editor/* gs://${{ env.GCP_BUCKET }}/generic-editor/ + rm -f /tmp/service-account-key.json + + - name: Upload to Azure Blob Storage + if: env.CLOUD_PROVIDER == 'azure' + uses: azure/CLI@v1 + with: + azcliversion: latest + inlineScript: | + az storage blob upload-batch \ + --account-name "${{ secrets.AZURE_STORAGE_ACCOUNT }}" \ + --account-key "${{ secrets.AZURE_STORAGE_KEY }}" \ + --destination "${{ vars.AZURE_CONTAINER }}/generic-editor" \ + --source generic-editor \ + --overwrite + +# Note: Publishing to AWS S3 is not tested. + + # - name: Configure AWS credentials + # if: env.CLOUD_PROVIDER == 'aws' + # uses: aws-actions/configure-aws-credentials@v4 + # with: + # aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + # aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + # aws-region: ${{ vars.AWS_REGION || 'us-east-1' }} + + # - name: Upload to Amazon S3 + # if: env.CLOUD_PROVIDER == 'aws' + # env: + # S3_BUCKET: ${{ vars.S3_BUCKET }} + # run: | + # aws s3 sync generic-editor s3://${{ env.S3_BUCKET }}/generic-editor/ diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000..ac21f0e --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,101 @@ +name: Build and Test on Pull Request + +on: + pull_request: + branches: + - '**' + +env: + CONTENT_PLUGIN_VERSION: ${{ vars.CONTENT_PLUGIN_VERSION || 'release-8.0.0' }} + +jobs: + build-test: + runs-on: ubuntu-latest + env: + version_number: ${{ github.ref_name }} + build_number: ${{ github.run_number }} + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js 10 + uses: actions/setup-node@v3 + with: + node-version: 10.24.1 + + - name: Cache node modules + uses: actions/cache@v3 + with: + path: node_modules + key: ${{ runner.os }}-node-${{ hashFiles('package.json') }} + + - name: Clone plugins (from fork) + run: | + git clone --branch ${{ env.CONTENT_PLUGIN_VERSION }} https://github.com/Sunbird-Knowlg/sunbird-content-plugins.git plugins + + - name: Install dependencies + run: | + which bower || sudo npm install -g bower@1.8.0 + which grunt || sudo npm install -g grunt-cli@1.2.0 + which gulp || sudo npm install -g gulp@3.9.1 + sudo apt-get install build-essential libpng-dev + + - name: Bower cache clean + working-directory: app + run: bower cache clean --allow-root + + - name: Bower install + working-directory: app + run: bower install --force --allow-root + + - name: Install global npm packages + run: npm install --legacy-peer-deps + + - name: Gulp packageCorePlugins + run: gulp packageCorePlugins + + - name: Plugin build + run: npm run plugin-build + + - name: Run build + run: npm run build + + - name: Test + run: npm run test + continue-on-error: true + + - name: Set up Node.js 14 (for Sonar) + uses: actions/setup-node@v3 + with: + node-version: 14 + + - name: Install SonarQube scanner + run: npm install -g sonarqube-scanner + + - name: Run SonarQube scanner + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: sonar-scanner + + lint: + needs: build-test + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js 18 + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Cache node modules + uses: actions/cache@v3 + with: + path: node_modules + key: ${{ runner.os }}-node-${{ hashFiles('package.json') }} + + - name: Run Lint + run: npm run lint diff --git a/README.md b/README.md index aabadd1..a43eb29 100644 --- a/README.md +++ b/README.md @@ -170,3 +170,91 @@ We use [SemVer](https://semver.org/) for versioning. For the versions available, ## Any Issues? We have an open and active [issue tracker](https://project-sunbird.atlassian.net/issues/). Please report any issues. + +# GitHub Actions + +## Build and Test on Pull Request + +This GitHub Actions workflow runs **build, test, and lint checks** automatically when a pull request is opened against any branch. + +### When It Runs + +- **Trigger**: On every `pull_request` to any branch (`'**'`) + +### Prerequisites Before Triggering + +Make sure the following are set up **before** opening a pull request: + +### Secrets +`SONAR_TOKEN`: For SonarQube authentication + +### Repository Variables +`CONTENT_PLUGIN_VERSION`: Have to specify the branch or tag you want fetch. By default it will take `release-8.0.0` + +Note: The secrets and variables should be set in Github UI (`settings/secrets and variables/actions`). + +For any changes to the workflow, update the file `.github/workflows/pull-request.yml` accordingly. + +# Build and Upload Generic Editor Workflow + +**Workflow Name:** `Publish Sunbird-generic-editor to blob` + +This GitHub Actions workflow builds the Generic Editor and uploads the generated build artifacts to a cloud storage provider — **GCP**, **Azure**, or **AWS**. +It is triggered **whenever a new Git tag is pushed** to the repository. + +--- + +## Prerequisites + +Before triggering this workflow, ensure the following: + +- A valid Git tag is pushed to start the workflow. +- The pushed tag **must also exist** in the [`sunbird-content-plugins`](https://github.com/project-sunbird/sunbird-content-plugins) repository. +- Required **GitHub Actions Variables** and **Secrets** are configured based on the selected cloud provider. + +You can set **Variables and Secrets** in GitHub under: +`Settings → Secrets and Variables → Actions` + +--- + +## Cloud Provider Configuration + +The workflow uses the `CLOUD_PROVIDER` variable to determine where to upload the build artifacts. Based on the provider selected, configure the following: + +### GCP (Google Cloud Platform) + +**Repository Variable:** +- `CLOUD_PROVIDER` = `gcp` +- `GCP_BUCKET` — Name of the GCP bucket to upload to. + +**Repository Secret:** +- `GCP_SERVICE_ACCOUNT_KEY` — Base64-encoded GCP service account key. + +--- + +### Azure + +**Repository Variable:** +- `CLOUD_PROVIDER` = `azure` +- `AZURE_CONTAINER` — Name of the Azure Blob Storage container. + +**Repository Secrets:** +- `AZURE_STORAGE_ACCOUNT` — Azure Storage account name. +- `AZURE_STORAGE_KEY` — Azure Storage account key. + +--- + +### AWS (Amazon Web Services) + +> **Note:** AWS upload is defined in the workflow but marked as **not tested**. + +**Repository Variable:** +- `CLOUD_PROVIDER` = `aws` +- `S3_BUCKET` — Name of the AWS S3 bucket. +- `AWS_REGION` — AWS region where the bucket is located. + +**Repository Secrets:** +- `AWS_ACCESS_KEY_ID` — AWS access key ID. +- `AWS_SECRET_ACCESS_KEY` — AWS secret access key. + +--- \ No newline at end of file diff --git a/package.json b/package.json index 0aa03b4..514fd4f 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,14 @@ "css-tree": "1.0.0-alpha.29", "csso": "3.5.1", "cssnano": "4.1.10", - "eslint": "^5.6.0", + "eslint": "^8.57.1", "global": "^4.4.0", "eslint-plugin-import": "^2.14.0", "eslint-plugin-node": "^7.0.1", "eslint-plugin-promise": "^4.0.1", "eslint-plugin-standard": "^4.0.0", + "eslint-config-standard": "^12.0.0", + "eslint-plugin-only-warn": "^1.0.4", "expose-loader": "^0.7.5", "express-http-proxy": "^1.2.0", "extract": "^1.0.0", @@ -105,7 +107,8 @@ "plugin-build": "webpack --config webpack.plugin.config.js", "build-editor": "npm run test && npm run collection-plugins && npm run build", "test": "karma start karmaconf.js", - "build-npm-pkg": "gulp packageCorePlugins && npm run plugin-build && webpack --env.channel=NPM_PACKAGE && cd generic-editor && gulp copystyleImages && gulp clean && gulp injectrenamedfiles" + "build-npm-pkg": "gulp packageCorePlugins && npm run plugin-build && webpack --env.channel=NPM_PACKAGE && cd generic-editor && gulp copystyleImages && gulp clean && gulp injectrenamedfiles", + "lint": "eslint . --quiet" }, "repository": { "type": "git",