diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..3118ddb --- /dev/null +++ b/.eslintrc @@ -0,0 +1,8 @@ +{ + "extends": "eslint-config-discourse", + "ignorePatterns": ["javascripts/vendor/*"], + "globals": { + "settings": "readonly", + "themePrefix": "readonly" + } +} diff --git a/.github/workflows/component-linting.yml b/.github/workflows/component-linting.yml new file mode 100644 index 0000000..2385132 --- /dev/null +++ b/.github/workflows/component-linting.yml @@ -0,0 +1,48 @@ +name: Linting + +on: + push: + branches: + - main + pull_request: + +concurrency: + group: plugin-linting-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: yarn + + - name: Yarn install + run: yarn install + + - name: ESLint + if: ${{ always() }} + run: yarn eslint --ext .js,.js.es6 --no-error-on-unmatched-pattern {test,javascripts} + + - name: Prettier + if: ${{ always() }} + shell: bash + run: | + yarn prettier -v + files=$(find javascripts desktop mobile common scss -type f \( -name "*.scss" -or -name "*.js" -or -name "*.es6" \) 2> /dev/null) || true + if [ -n "$files" ]; then + yarn prettier --list-different $files + fi + if [ 0 -lt $(find test -type f \( -name "*.js" -or -name "*.es6" \) 2> /dev/null | wc -l) ]; then + yarn prettier --list-different "test/**/*.{js,es6}" + fi + + - name: Ember template lint + if: ${{ always() }} + run: yarn ember-template-lint --no-error-on-unmatched-pattern javascripts diff --git a/.github/workflows/component-tests.yml b/.github/workflows/component-tests.yml new file mode 100644 index 0000000..944aa1e --- /dev/null +++ b/.github/workflows/component-tests.yml @@ -0,0 +1,147 @@ +name: Tests + +on: + push: + branches: + - main + pull_request: + +concurrency: + group: plugin-tests-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }} + cancel-in-progress: true + +jobs: + check: + runs-on: ubuntu-latest + outputs: + tests_exist: ${{ steps.check_tests.outputs.tests_exist }} + + steps: + - name: Install component + uses: actions/checkout@v3 + with: + path: tmp/component + fetch-depth: 1 + + - name: Check QUnit existence + id: check_tests + shell: bash + run: | + if [ 0 -lt $(find tmp/component/test -type f \( -name "*.js" -or -name "*.es6" \) 2> /dev/null | wc -l) ]; then + echo "::set-output name=tests_exist::true" + fi + + test: + needs: check + if: ${{ needs.check.outputs.tests_exist }} + runs-on: ubuntu-latest + container: discourse/discourse_test:slim-browsers + timeout-minutes: 15 + + env: + DISCOURSE_HOSTNAME: www.example.com + RUBY_GLOBAL_METHOD_CACHE_SIZE: 131072 + RAILS_ENV: development + PGUSER: discourse + PGPASSWORD: discourse + + steps: + - uses: actions/checkout@v3 + with: + repository: discourse/discourse + fetch-depth: 1 + + - name: Install component + uses: actions/checkout@v3 + with: + path: tmp/component + fetch-depth: 1 + + - name: Setup Git + run: | + git config --global user.email "ci@ci.invalid" + git config --global user.name "Discourse CI" + + - name: Start redis + run: | + redis-server /etc/redis/redis.conf & + + - name: Start Postgres + run: | + chown -R postgres /var/run/postgresql + sudo -E -u postgres script/start_test_db.rb + sudo -u postgres psql -c "CREATE ROLE $PGUSER LOGIN SUPERUSER PASSWORD '$PGPASSWORD';" + + - name: Bundler cache + uses: actions/cache@v3 + with: + path: vendor/bundle + key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ${{ runner.os }}-gem- + + - name: Setup gems + run: | + gem install bundler --conservative -v $(awk '/BUNDLED WITH/ { getline; gsub(/ /,""); print $0 }' Gemfile.lock) + bundle config --local path vendor/bundle + bundle config --local deployment true + bundle config --local without development + bundle install --jobs 4 + bundle clean + + - name: Lint English locale + run: bundle exec ruby script/i18n_lint.rb "tmp/component/locales/en.yml" + + - name: Get yarn cache directory + id: yarn-cache-dir + run: echo "::set-output name=dir::$(yarn cache dir)" + + - name: Yarn cache + uses: actions/cache@v3 + id: yarn-cache + with: + path: ${{ steps.yarn-cache-dir.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Yarn install + run: yarn install + + - name: Fetch app state cache + uses: actions/cache@v3 + id: app-cache + with: + path: tmp/app-cache + key: >- + ${{ hashFiles('.github/workflows/tests.yml') }}- + ${{ hashFiles('db/**/*', 'plugins/**/db/**/*') }}- + + - name: Restore database from cache + if: steps.app-cache.outputs.cache-hit == 'true' + run: psql -f tmp/app-cache/cache.sql postgres + + - name: Restore uploads from cache + if: steps.app-cache.outputs.cache-hit == 'true' + run: rm -rf public/uploads && cp -r tmp/app-cache/uploads public/uploads + + - name: Create and migrate database + if: steps.app-cache.outputs.cache-hit != 'true' + run: | + bin/rake db:create + bin/rake db:migrate + + - name: Dump database for cache + if: steps.app-cache.outputs.cache-hit != 'true' + run: mkdir -p tmp/app-cache && pg_dumpall > tmp/app-cache/cache.sql + + - name: Dump uploads for cache + if: steps.app-cache.outputs.cache-hit != 'true' + run: rm -rf tmp/app-cache/uploads && cp -r public/uploads tmp/app-cache/uploads + + - name: Component QUnit + run: | + THEME_NAME=$(ruby -e 'require "json"; puts JSON.parse(File.read("tmp/component/about.json"))["name"]') + bundle exec rake themes:install -- "--{\"$THEME_NAME\": \"tmp/component\"}" + UNICORN_TIMEOUT=120 bundle exec rake "themes:qunit[name,$THEME_NAME]" + timeout-minutes: 10 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..14735c6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +.discourse-site diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/.prettierrc @@ -0,0 +1 @@ +{} diff --git a/.template-lintrc.js b/.template-lintrc.js new file mode 100644 index 0000000..a558b8e --- /dev/null +++ b/.template-lintrc.js @@ -0,0 +1,4 @@ +module.exports = { + plugins: ["ember-template-lint-plugin-discourse"], + extends: "discourse:recommended", +}; diff --git a/about.json b/about.json index e097a0d..7958722 100644 --- a/about.json +++ b/about.json @@ -1,6 +1,5 @@ { "name": "Header submenus", - "about_url": "https://meta.discourse.org/t/", - "license_url": "https://github.com/discourse/discourse-header-submenus/blob/main/LICENSE", - "component": true + "component": true, + "license_url": "https://github.com/discourse/discourse-header-submenus/blob/main/LICENSE" } diff --git a/javascripts/discourse/connectors/above-site-header/header-submenus.hbs b/javascripts/discourse/connectors/above-site-header/header-submenus.hbs index 938eca3..9f23475 100644 --- a/javascripts/discourse/connectors/above-site-header/header-submenus.hbs +++ b/javascripts/discourse/connectors/above-site-header/header-submenus.hbs @@ -1,28 +1,40 @@ -
-