From 6c06e5b62ad08a6b39568a025f23ffc5edc7d6e9 Mon Sep 17 00:00:00 2001 From: Johannes Hoppe Date: Mon, 8 Jun 2026 16:14:55 +0200 Subject: [PATCH 1/4] feat: add support for Angular 22 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extends the supported Angular range from 18–21 to 18–22. - package.json: bump devkit upper bounds (architect <0.2300.0, core/schematics <23.0.0) and the @angular/cli peer to <23.0.0; v3.1.0 - README: update supported range to "Angular 18 to 22" - CI: add an Angular 22 ng new / ng add / ng deploy smoke test - tests: add angular-22.json fixture (real ng new v22.0.0 output) plus Angular 22 compatibility assertions No engine/builder changes needed: Angular 22's generated angular.json is structurally identical to 21 (@angular/build:application, no outputPath), which actions.ts already handles. --- .github/workflows/main.yml | 13 ++++ README.md | 2 +- src/package.json | 10 +-- src/test-fixtures/angular-22.json | 73 ++++++++++++++++++++++ src/test-fixtures/angular-versions.spec.ts | 25 +++++++- 5 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 src/test-fixtures/angular-22.json diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ac42c4e..d47c6ce 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -124,3 +124,16 @@ jobs: npx ng deploy cd /tmp/remote-21.git && git branch | grep gh-pages echo "Angular 21: build + deploy successful" + + - name: Test Angular 22 + run: | + cd /tmp + git init --bare remote-22.git + npx @angular/cli@22 new test-app-22 --defaults + cd test-app-22 + git remote add origin /tmp/remote-22.git + npm link angular-cli-ghpages + npx ng add angular-cli-ghpages + npx ng deploy + cd /tmp/remote-22.git && git branch | grep gh-pages + echo "Angular 22: build + deploy successful" diff --git a/README.md b/README.md index 97408ca..d7cff71 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ A detailed changelog is available in the [releases](https://github.com/angular-schule/angular-cli-ghpages/releases) section. -`angular-cli-ghpages` v3 supports Angular 18 to 21. +`angular-cli-ghpages` v3 supports Angular 18 to 22. For previous versions of Angular, use v1 or v2. ## ⚠️ Prerequisites diff --git a/src/package.json b/src/package.json index 759a74b..9878d6a 100644 --- a/src/package.json +++ b/src/package.json @@ -1,6 +1,6 @@ { "name": "angular-cli-ghpages", - "version": "3.0.3", + "version": "3.1.0", "description": "Deploy your Angular app to GitHub Pages or Cloudflare Pages directly from the Angular CLI (ng deploy)", "main": "index.js", "types": "index.d.ts", @@ -71,12 +71,12 @@ "typescript": "~5.2.2" }, "dependencies": { - "@angular-devkit/architect": ">=0.1800.0 <0.2200.0", - "@angular-devkit/core": ">=18.0.0 <22.0.0", - "@angular-devkit/schematics": ">=18.0.0 <22.0.0", + "@angular-devkit/architect": ">=0.1800.0 <0.2300.0", + "@angular-devkit/core": ">=18.0.0 <23.0.0", + "@angular-devkit/schematics": ">=18.0.0 <23.0.0", "gh-pages": "6.3.0" }, "peerDependencies": { - "@angular/cli": ">=18.0.0 <22.0.0" + "@angular/cli": ">=18.0.0 <23.0.0" } } diff --git a/src/test-fixtures/angular-22.json b/src/test-fixtures/angular-22.json new file mode 100644 index 0000000..8b6a50d --- /dev/null +++ b/src/test-fixtures/angular-22.json @@ -0,0 +1,73 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "cli": { + "packageManager": "npm" + }, + "newProjectRoot": "projects", + "projects": { + "ng22": { + "projectType": "application", + "schematics": {}, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "browser": "src/main.ts", + "tsConfig": "tsconfig.app.json", + "assets": [ + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.css" + ] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kB", + "maximumError": "1MB" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kB", + "maximumError": "8kB" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular/build:dev-server", + "configurations": { + "production": { + "buildTarget": "ng22:build:production" + }, + "development": { + "buildTarget": "ng22:build:development" + } + }, + "defaultConfiguration": "development" + }, + "test": { + "builder": "@angular/build:unit-test" + } + } + } + } +} diff --git a/src/test-fixtures/angular-versions.spec.ts b/src/test-fixtures/angular-versions.spec.ts index 99e58c3..fda4b23 100644 --- a/src/test-fixtures/angular-versions.spec.ts +++ b/src/test-fixtures/angular-versions.spec.ts @@ -7,7 +7,7 @@ * * Key difference relevant to us: * - Angular 18-19: outputPath is a string like "dist/" - * - Angular 20-21: outputPath is MISSING (uses default dist/) + * - Angular 20-22: outputPath is MISSING (uses default dist/) */ import { SchematicContext, Tree } from '@angular-devkit/schematics'; @@ -34,6 +34,7 @@ const angular18Config = JSON.parse(fs.readFileSync(path.join(fixturesDir, 'angul const angular19Config = JSON.parse(fs.readFileSync(path.join(fixturesDir, 'angular-19.json'), 'utf-8')); const angular20Config = JSON.parse(fs.readFileSync(path.join(fixturesDir, 'angular-20.json'), 'utf-8')); const angular21Config = JSON.parse(fs.readFileSync(path.join(fixturesDir, 'angular-21.json'), 'utf-8')); +const angular22Config = JSON.parse(fs.readFileSync(path.join(fixturesDir, 'angular-22.json'), 'utf-8')); describe('Angular Version Compatibility', () => { describe('Angular 18', () => { @@ -104,12 +105,30 @@ describe('Angular Version Compatibility', () => { }); }); + describe('Angular 22', () => { + it('has NO outputPath (uses default)', () => { + const options = angular22Config.projects.ng22.architect.build.options; + expect(options.outputPath).toBeUndefined(); + }); + + it('ng add succeeds despite missing outputPath', async () => { + const tree = Tree.empty(); + tree.create('angular.json', JSON.stringify(angular22Config)); + + const result = await ngAdd({ project: 'ng22' })(tree, mockContext); + const resultConfig = JSON.parse(result.read('angular.json')!.toString()); + + expect(resultConfig.projects.ng22.architect.deploy.builder).toBe('angular-cli-ghpages:deploy'); + }); + }); + describe('Cross-version compatibility', () => { it('all versions have projectType: application', () => { expect(angular18Config.projects.ng18.projectType).toBe('application'); expect(angular19Config.projects.ng19.projectType).toBe('application'); expect(angular20Config.projects.ng20.projectType).toBe('application'); expect(angular21Config.projects.ng21.projectType).toBe('application'); + expect(angular22Config.projects.ng22.projectType).toBe('application'); }); it('all versions have build target', () => { @@ -117,13 +136,15 @@ describe('Angular Version Compatibility', () => { expect(angular19Config.projects.ng19.architect.build).toBeDefined(); expect(angular20Config.projects.ng20.architect.build).toBeDefined(); expect(angular21Config.projects.ng21.architect.build).toBeDefined(); + expect(angular22Config.projects.ng22.architect.build).toBeDefined(); }); - it('outputPath evolution: string → string → undefined → undefined', () => { + it('outputPath evolution: string → string → undefined → undefined → undefined', () => { expect(typeof angular18Config.projects.ng18.architect.build.options.outputPath).toBe('string'); expect(typeof angular19Config.projects.ng19.architect.build.options.outputPath).toBe('string'); expect(angular20Config.projects.ng20.architect.build.options.outputPath).toBeUndefined(); expect(angular21Config.projects.ng21.architect.build.options.outputPath).toBeUndefined(); + expect(angular22Config.projects.ng22.architect.build.options.outputPath).toBeUndefined(); }); }); }); From 0c0aed00cb1392586910ac2e123309e261d7838d Mon Sep 17 00:00:00 2001 From: Johannes Hoppe Date: Mon, 8 Jun 2026 16:27:14 +0200 Subject: [PATCH 2/4] chore: port Node version range improvement from #211 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #211 rightly flagged that engines.node ">=18.0.0" is stale — no supported Angular actually runs on Node 18.0–18.18 (Angular 18's real floor is 18.19.1). It set "^20.19.0 || ^22.12.0 || >=24.0.0", but that is Angular 20/21's requirement and is too narrow here: it locks out Node 18/19 needed by the Angular 18/19 users this PR still supports, plus odd majors. Bump to a wide lower bound at the true floor of the oldest supported Angular (18 → 18.19.1). Angular CLI enforces its own stricter per-version Node gate, so we only need a sane floor, not a duplicate of it. --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index 9878d6a..63973d1 100644 --- a/src/package.json +++ b/src/package.json @@ -5,7 +5,7 @@ "main": "index.js", "types": "index.d.ts", "engines": { - "node": ">=18.0.0", + "node": ">=18.19.1", "npm": ">=9.0.0" }, "bin": { From 3143ea4e58541238cf08703f087fa5fe3672aacc Mon Sep 17 00:00:00 2001 From: Johannes Hoppe Date: Mon, 8 Jun 2026 16:31:26 +0200 Subject: [PATCH 3/4] ci: run "Build and test" on pull requests + enable manual dispatch The workflow only triggered on push to main/big-update, so pull requests (including this one) received no CI at all. Add a pull_request trigger (targeting main) so PRs are validated before merge, plus workflow_dispatch for on-demand runs (becomes usable once this lands on the default branch). --- .github/workflows/main.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d47c6ce..3ec9ac7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -3,6 +3,9 @@ name: Build and test on: push: branches: [main, big-update] + pull_request: + branches: [main] + workflow_dispatch: jobs: build-and-test: From 15c4c437dacf5937b69e77e6dcec23b980bc67f1 Mon Sep 17 00:00:00 2001 From: Johannes Hoppe Date: Mon, 8 Jun 2026 16:42:07 +0200 Subject: [PATCH 4/4] ci: drop completed big-update branch from push triggers --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3ec9ac7..3845c3f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,7 +2,7 @@ name: Build and test on: push: - branches: [main, big-update] + branches: [main] pull_request: branches: [main] workflow_dispatch: