From df745b95c15e8e6bbe575ea5a3aa0223c1532588 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 8 Sep 2026 11:08:22 +0200 Subject: [PATCH 1/2] build: rebuild the asset pipeline on gulp 5, clear all Dependabot alerts The gulpfile used gulp 3's array-of-dependencies task signature (`gulp.task('x', ['a','b'])`), which gulp 4 removed in 2018 while package.json declared gulp 5.0.1. Every gulp invocation aborted at load with "AssertionError: Task function must be specified", so no asset change could be compiled. It also passed autoprefixer's `browsers` option, removed in autoprefixer 4. Rebuilt on gulp 5 with maintained plugins: - gulp.series / gulp.parallel in place of the array signature - gulp-terser replaces gulp-uglify - gulp-postcss + autoprefixer replaces gulp-autoprefixer, with the browser targets coming from .browserslistrc rather than the removed `browsers` option - gulp 5's built-in `{ sourcemaps: true }` replaces gulp-sourcemaps, which is unmaintained and was the only thing pulling postcss 7 - the .po -> .mo step moves to WP-CLI (`npm run build:mo`), replacing gulp-gettext, which depends on the abandoned gulp-util Dropped as unused: gulp-util (only ever `gutil.log` in an error handler, now console.error), gulp-jshint and jshint (the reporter was already commented out), gulp-minify-css (imported, never piped), gulp-concat (concatenating a single file) and map-stream. Removed the "dependencies" block: acorn, atob, braces, clean-css, cryptiles, hoek, lodash, lodash.template, minimatch, minimist, randomatic, tar and tunnel-agent. None is imported by any source file - they are leftover `npm audit fix` pins, and declaring them as runtime dependencies is why Dependabot reported hoek and lodash.template under runtime scope for a plugin that ships PHP and built assets only. Both had no patched version available and could only be resolved by removing the package. All 13 Dependabot alerts are cleared and `npm audit` reports 0 vulnerabilities, down from a 426-package tree to 260. Assets: lsx-login.css and lsx-login-rtl.css are now compiled compressed rather than compact - dart-sass does not support the compact output style. The rules are unchanged; the files are ~180 bytes smaller each. Version: the plugin header and LSX_LOGIN_VER were still on 1.0.5 while changelog.txt had already shipped 1.1.2 and opened 1.1.3. Both now read 1.1.3, matching the changelog, and the enqueues already version off LSX_LOGIN_VER so the cache bust follows. Also removed: - .travis.yml - targeting a service no longer running these builds - .mergify.yml - auto-merged every Dependabot PR unreviewed; Mergify is no longer in use here - lsx-login.sublime-project - editor-local file Added .github/workflows/ci.yml: - PHP syntax lint across 8.2/8.3/8.4, excluding the bundled vendor/ libraries (Custom-Meta-Boxes, uix), which predate PHP 8 and are not ours - an assets job that rebuilds CSS and JS and fails on a diff, so a source-only change cannot ship stale output It uses GitHub's native `concurrency` with cancel-in-progress rather than the styfle/cancel-workflow-action pattern used elsewhere in the org. Updated .github/dependabot.yml: weekly grouped updates with a limit of 5, replacing daily updates with a limit of 99. --- .browserslistrc | 5 + .github/dependabot.yml | 35 +- .github/workflows/ci.yml | 62 + .gitignore | 1 + .mergify.yml | 24 - .nvmrc | 1 + .travis.yml | 90 - assets/css/lsx-login-rtl.css | 23 +- assets/css/lsx-login.css | 25 +- assets/css/maps/lsx-login.css.map | 2 +- assets/js/lsx-login.min.js | 2 +- changelog.txt | 6 + gulpfile.js | 236 +- lsx-login.php | 4 +- lsx-login.sublime-project | 16 - package-lock.json | 3716 ++++++++++------------------- package.json | 63 +- 17 files changed, 1549 insertions(+), 2762 deletions(-) create mode 100644 .browserslistrc create mode 100644 .github/workflows/ci.yml delete mode 100644 .mergify.yml create mode 100644 .nvmrc delete mode 100644 .travis.yml delete mode 100644 lsx-login.sublime-project diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 0000000..180df7c --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,5 @@ +# Carried over from the browserlist array in the previous gulpfile. +# autoprefixer reads this; the `browsers` option it used to take was removed +# in autoprefixer 4. +last 2 versions +> 1% diff --git a/.github/dependabot.yml b/.github/dependabot.yml index bdff2c7..15dd9d1 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,9 +1,30 @@ version: 2 + updates: -- package-ecosystem: npm - directory: "/" - schedule: - interval: daily - time: "03:00" - timezone: Africa/Johannesburg - open-pull-requests-limit: 99 + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + day: monday + time: "03:00" + timezone: Africa/Johannesburg + open-pull-requests-limit: 5 + # Grouped updates: one PR for all action bumps rather than one per action. + groups: + github-actions: + patterns: + - "*" + + - package-ecosystem: npm + directory: "/" + schedule: + interval: weekly + day: monday + time: "03:00" + timezone: Africa/Johannesburg + open-pull-requests-limit: 5 + groups: + npm-development: + dependency-type: development + patterns: + - "*" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f4667b2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,62 @@ +name: CI + +on: + push: + branches: [master, develop] + pull_request: + +# Supersedes the old cancel.yml / styfle/cancel-workflow-action pattern: +# GitHub cancels superseded runs natively per ref. +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + php: + name: PHP ${{ matrix.php }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php: ['8.2', '8.3', '8.4'] + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + + # vendor/ holds bundled third-party libraries (Custom-Meta-Boxes, uix) + # that predate PHP 8 and are not ours to fix, so they stay out of scope. + - name: Lint PHP syntax + run: | + git ls-files '*.php' ':!:vendor/**' | xargs -r -n1 -P4 php -l + + assets: + name: Built assets are current + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + + - uses: actions/setup-node@v7 + with: + node-version-file: '.nvmrc' + cache: npm + + - run: npm ci + + - name: Rebuild CSS and JS + run: npm run build + + # The committed assets must match what the sources compile to, so a + # source-only change cannot ship stale output. + - name: Fail if the committed output is stale + run: git diff --exit-code -- assets/css assets/js diff --git a/.gitignore b/.gitignore index 0f85f98..e6b902d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules .sass-cache .idea +*.sublime-project *.sublime-workspace diff --git a/.mergify.yml b/.mergify.yml deleted file mode 100644 index 25d021c..0000000 --- a/.mergify.yml +++ /dev/null @@ -1,24 +0,0 @@ -pull_request_rules: - - name: automatic merge for Dependabot pull requests - conditions: - - author~=^dependabot(|-preview)\[bot\]$ - actions: - merge: - method: merge - - name: automatic merge for Renovate pull requests - conditions: - - author=renovate[bot] - actions: - merge: - method: merge - - name: automatic merge for ImgBot pull requests - conditions: - - author=imgbot[bot] - actions: - merge: - method: merge - - name: delete head branch on merged pull requests - conditions: - - merged - actions: - delete_head_branch: \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..b7179ae --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +24.20.0 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 933b445..0000000 --- a/.travis.yml +++ /dev/null @@ -1,90 +0,0 @@ -language: php -dist: xenial - -services: - - mysql - -notifications: - email: - on_success: never - on_failure: change - -cache: - directories: - - $HOME/.composer/cache - -php: - - 7.4 - - 7.1 - -env: - - WP_VERSION=latest - -matrix: - fast_finish: true - include: - - name: Coding Standards - php: 7.4 - env: WP_VERSION=latest RUN_PHPCS=1 - - name: Code Coverage - php: 7.1 - env: WP_VERSION=latest RUN_CODE_COVERAGE=1 - - name: Bleeding Edge - php: nightly - env: WP_VERSION=trunk - allow_failures: - - name: Code Coverage - - name: Bleeding Edge - -before_install: - - phpenv config-rm xdebug.ini || true - -# Use this to prepare the system to install prerequisites or dependencies. -# e.g. sudo apt-get update. -# Failures in this section will result in build status 'errored'. -# before_install: - -# Use this to prepare your build for testing. -# e.g. copy database configurations, environment variables, etc. -# Failures in this section will result in build status 'errored'. -before_script: - # Set up WordPress installation. - - export WP_DEVELOP_DIR=/tmp/wordpress/ - - mkdir -p $WP_DEVELOP_DIR - # Use the Git mirror of WordPress. - #- git clone --depth=1 --branch="$WP_VERSION" git://develop.git.wordpress.org/ $WP_DEVELOP_DIR - # Set up theme information. - - theme_slug=$(basename $(pwd)) - #- theme_dir=$WP_DEVELOP_DIR/src/wp-content/themes/$theme_slug - - theme_dir=$WP_DEVELOP_DIR/$theme_slug - - cd .. - - mv $theme_slug $theme_dir - # Set up WordPress configuration. - - cd $WP_DEVELOP_DIR - - echo $WP_DEVELOP_DIR - #- cp wp-tests-config-sample.php wp-tests-config.php - #- sed -i "s/youremptytestdbnamehere/wordpress_test/" wp-tests-config.php - #- sed -i "s/yourusernamehere/root/" wp-tests-config.php - #- sed -i "s/yourpasswordhere//" wp-tests-config.php - # Create WordPress database. - #- mysql -e 'CREATE DATABASE wordpress_test;' -uroot - # Install CodeSniffer for WordPress Coding Standards checks. - - git clone --branch 2.9.2 --single-branch https://github.com/squizlabs/PHP_CodeSniffer.git php-codesniffer --depth=1 - # Install WordPress Coding Standards. - - git clone --branch 0.11.0 --single-branch https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git wordpress-coding-standards --depth=1 - # Hop into CodeSniffer directory. - - cd php-codesniffer - # Set install path for WordPress Coding Standards. - # @link https://github.com/squizlabs/PHP_CodeSniffer/blob/4237c2fc98cc838730b76ee9cee316f99286a2a7/CodeSniffer.php#L1941 - - scripts/phpcs --config-set installed_paths ../wordpress-coding-standards - # Hop into themes directory. - - cd $theme_dir - # After CodeSniffer install you should refresh your path. - - phpenv rehash - -# Run test script commands. -# Default is specific to project language. -# All commands must exit with code 0 on success. Anything else is considered failure. -script: - # Search for PHP syntax errors. - - find . \( -name '*.php' \) -exec php -lf {} \; diff --git a/assets/css/lsx-login-rtl.css b/assets/css/lsx-login-rtl.css index 99550d5..3941c57 100644 --- a/assets/css/lsx-login-rtl.css +++ b/assets/css/lsx-login-rtl.css @@ -1,22 +1 @@ -/* Login Form + Reset Password Form Basic Styling */ -.loginform, .lostpasswordform { padding: 15px; } - -.loginform h3 .genericon, .lostpasswordform h3 .genericon { font-size: larger; padding-bottom: 1px; vertical-align: text-bottom; } - -.loginform .spinner, .lostpasswordform .spinner { position: absolute; } - -.loginform .error, .lostpasswordform .error { border-color: red; } - -.loginform p, .lostpasswordform p { width: 80%; } - -.loginform p label, .loginform p span, .loginform p input[type="text"], .loginform p input[type="password"], .lostpasswordform p label, .lostpasswordform p span, .lostpasswordform p input[type="text"], .lostpasswordform p input[type="password"] { width: 100% !important; } - -.loginform p input[type="text"], .lostpasswordform p input[type="text"] { width: auto; } - -.loginform p input[type="text"].error, .lostpasswordform p input[type="text"].error { background-color: #f3cdcd; } - -.loginform p.login-remember input, .lostpasswordform p.login-remember input { float: none; height: auto; margin-left: 5px; margin-top: 0; width: auto; } - -.loginform p.login-remember label, .loginform p.login-remember input, .lostpasswordform p.login-remember label, .lostpasswordform p.login-remember input { display: inline; } - -.loginform.loading p, .lostpasswordform.loading p { background-color: #ccc; opacity: 0.3; } +.loginform,.lostpasswordform{padding:15px}.loginform h3 .genericon,.lostpasswordform h3 .genericon{font-size:larger;padding-bottom:1px;vertical-align:text-bottom}.loginform .spinner,.lostpasswordform .spinner{position:absolute}.loginform .error,.lostpasswordform .error{border-color:red}.loginform p,.lostpasswordform p{width:80%}.loginform p label,.loginform p span,.loginform p input[type=text],.loginform p input[type=password],.lostpasswordform p label,.lostpasswordform p span,.lostpasswordform p input[type=text],.lostpasswordform p input[type=password]{width:100% !important}.loginform p input[type=text],.lostpasswordform p input[type=text]{width:auto}.loginform p input[type=text].error,.lostpasswordform p input[type=text].error{background-color:#f3cdcd}.loginform p.login-remember input,.lostpasswordform p.login-remember input{float:none;height:auto;margin-left:5px;margin-top:0;width:auto}.loginform p.login-remember label,.loginform p.login-remember input,.lostpasswordform p.login-remember label,.lostpasswordform p.login-remember input{display:inline}.loginform.loading p,.lostpasswordform.loading p{background-color:#ccc;opacity:.3} \ No newline at end of file diff --git a/assets/css/lsx-login.css b/assets/css/lsx-login.css index ff0fabb..e74b002 100644 --- a/assets/css/lsx-login.css +++ b/assets/css/lsx-login.css @@ -1,24 +1 @@ -/* Login Form + Reset Password Form Basic Styling */ -.loginform, .lostpasswordform { padding: 15px; } - -.loginform h3 .genericon, .lostpasswordform h3 .genericon { font-size: larger; padding-bottom: 1px; vertical-align: text-bottom; } - -.loginform .spinner, .lostpasswordform .spinner { position: absolute; } - -.loginform .error, .lostpasswordform .error { border-color: red; } - -.loginform p, .lostpasswordform p { width: 80%; } - -.loginform p label, .loginform p span, .loginform p input[type="text"], .loginform p input[type="password"], .lostpasswordform p label, .lostpasswordform p span, .lostpasswordform p input[type="text"], .lostpasswordform p input[type="password"] { width: 100% !important; } - -.loginform p input[type="text"], .lostpasswordform p input[type="text"] { width: auto; } - -.loginform p input[type="text"].error, .lostpasswordform p input[type="text"].error { background-color: #f3cdcd; } - -.loginform p.login-remember input, .lostpasswordform p.login-remember input { float: none; height: auto; margin-right: 5px; margin-top: 0; width: auto; } - -.loginform p.login-remember label, .loginform p.login-remember input, .lostpasswordform p.login-remember label, .lostpasswordform p.login-remember input { display: inline; } - -.loginform.loading p, .lostpasswordform.loading p { background-color: #ccc; opacity: 0.3; } - -/*# sourceMappingURL=maps/lsx-login.css.map */ +.loginform,.lostpasswordform{padding:15px}.loginform h3 .genericon,.lostpasswordform h3 .genericon{font-size:larger;padding-bottom:1px;vertical-align:text-bottom}.loginform .spinner,.lostpasswordform .spinner{position:absolute}.loginform .error,.lostpasswordform .error{border-color:red}.loginform p,.lostpasswordform p{width:80%}.loginform p label,.loginform p span,.loginform p input[type=text],.loginform p input[type=password],.lostpasswordform p label,.lostpasswordform p span,.lostpasswordform p input[type=text],.lostpasswordform p input[type=password]{width:100% !important}.loginform p input[type=text],.lostpasswordform p input[type=text]{width:auto}.loginform p input[type=text].error,.lostpasswordform p input[type=text].error{background-color:#f3cdcd}.loginform p.login-remember input,.lostpasswordform p.login-remember input{float:none;height:auto;margin-right:5px;margin-top:0;width:auto}.loginform p.login-remember label,.loginform p.login-remember input,.lostpasswordform p.login-remember label,.lostpasswordform p.login-remember input{display:inline}.loginform.loading p,.lostpasswordform.loading p{background-color:#ccc;opacity:.3}/*# sourceMappingURL=maps/lsx-login.css.map */ diff --git a/assets/css/maps/lsx-login.css.map b/assets/css/maps/lsx-login.css.map index b1c432e..0924972 100644 --- a/assets/css/maps/lsx-login.css.map +++ b/assets/css/maps/lsx-login.css.map @@ -1 +1 @@ -{"version":3,"sources":["lsx-login.scss"],"names":[],"mappings":"AAAA,oDAEG;AACH,gCAEC,cAAY,EAkDZ;;AApDD,4DAKE,kBAAiB,CACjB,oBAAmB,CACnB,4BAA2B,EAC3B;;AARF,kDAWE,mBAAiB,EACjB;;AAZF,8CAeE,kBAAgB,EAChB;;AAhBF,oCAmBE,WAAS,EA2BT;;AA9CF,uPAsBG,uBAAqB,EACrB;;AAvBH,0EA0BG,YAAU,EAKV;;AA/BH,sFA6BI,0BAAwB,EACxB;;AA9BJ,8EAmCI,YAAW,CACX,aAAY,CACZ,kBAAiB,CACjB,cAAa,CACb,YAAW,EACX;;AAxCJ,2JA2CI,gBAAe,EACf;;AA5CJ,oDAiDE,uBAAsB,CACtB,aAAY,EACZ","file":"../lsx-login.css","sourcesContent":["/*\n * Login Form + Reset Password Form Basic Styling\n */\n.loginform , .lostpasswordform {\n\n\tpadding:15px;\n\n\th3 .genericon {\n\t\tfont-size: larger;\n\t\tpadding-bottom: 1px;\n\t\tvertical-align: text-bottom;\n\t}\n\n\t.spinner {\n\t\tposition:absolute;\n\t}\n\n\t.error{\n\t\tborder-color:red;\n\t}\n\n\tp{\n\t\twidth:80%;\n\n\t\tlabel, span, input[type=\"text\"],input[type=\"password\"] {\n\t\t\twidth:100% !important;\n\t\t}\n\n\t\tinput[type=\"text\"]{\n\t\t\twidth:auto;\n\n\t\t\t&.error {\n\t\t\t\tbackground-color:#f3cdcd;\n\t\t\t}\n\t\t}\n\n\t\t&.login-remember {\n\t\t\tinput {\n\t\t\t\tfloat: none;\n\t\t\t\theight: auto;\n\t\t\t\tmargin-right: 5px;\n\t\t\t\tmargin-top: 0;\n\t\t\t\twidth: auto;\n\t\t\t}\n\n\t\t\tlabel,input{\n\t\t\t\tdisplay: inline;\n\t\t\t}\n\t\t}\n\t}\n\n\t&.loading p {\n\t\tbackground-color: #ccc;\n\t\topacity: 0.3;\n\t}\n}"]} \ No newline at end of file +{"version":3,"sources":["lsx-login.scss"],"names":[],"mappings":"AAGA,6BAEC,YAAA,CAEA,yDACC,gBAAA,CACA,kBAAA,CACA,0BAAA,CAGD,+CACC,iBAAA,CAGD,2CACC,gBAAA,CAGD,iCACC,SAAA,CAEA,sOACC,qBAAA,CAGD,mEACC,UAAA,CAEA,+EACC,wBAAA,CAKD,2EACC,UAAA,CACA,WAAA,CACA,gBAAA,CACA,YAAA,CACA,UAAA,CAGD,sJACC,cAAA,CAKH,iDACC,qBAAA,CACA,UAAA","file":"lsx-login.css","sourcesContent":["/*\n * Login Form + Reset Password Form Basic Styling\n */\n.loginform , .lostpasswordform {\n\n\tpadding:15px;\n\n\th3 .genericon {\n\t\tfont-size: larger;\n\t\tpadding-bottom: 1px;\n\t\tvertical-align: text-bottom;\n\t}\n\n\t.spinner {\n\t\tposition:absolute;\n\t}\n\n\t.error{\n\t\tborder-color:red;\n\t}\n\n\tp{\n\t\twidth:80%;\n\n\t\tlabel, span, input[type=\"text\"],input[type=\"password\"] {\n\t\t\twidth:100% !important;\n\t\t}\n\n\t\tinput[type=\"text\"]{\n\t\t\twidth:auto;\n\n\t\t\t&.error {\n\t\t\t\tbackground-color:#f3cdcd;\n\t\t\t}\n\t\t}\n\n\t\t&.login-remember {\n\t\t\tinput {\n\t\t\t\tfloat: none;\n\t\t\t\theight: auto;\n\t\t\t\tmargin-right: 5px;\n\t\t\t\tmargin-top: 0;\n\t\t\t\twidth: auto;\n\t\t\t}\n\n\t\t\tlabel,input{\n\t\t\t\tdisplay: inline;\n\t\t\t}\n\t\t}\n\t}\n\n\t&.loading p {\n\t\tbackground-color: #ccc;\n\t\topacity: 0.3;\n\t}\n}"]} \ No newline at end of file diff --git a/assets/js/lsx-login.min.js b/assets/js/lsx-login.min.js index 66c2bd3..7ffe897 100644 --- a/assets/js/lsx-login.min.js +++ b/assets/js/lsx-login.min.js @@ -1 +1 @@ -function getQueryString(){var s=!1,i={},e=null,a=location.search.substring(1);0'+lsx_login_params.empty_username+""),l(this).find("input.user_login").addClass("error"),!1;var a=l(this).find("input.user_pass").val();if(""==a)return l(this).find("input.user_pass").parent("p").append('
'+lsx_login_params.empty_password+"
"),l(this).find("input.user_pass").addClass("error"),!1;var r="";0