diff --git a/.cspell.json b/.cspell.json index cfc24d9..1c3e15e 100644 --- a/.cspell.json +++ b/.cspell.json @@ -14,6 +14,7 @@ "eslint-plugin", "parser", "cspell", + "dry-aged-deps", "eslint-config-prettier", "eslint-import-resolver-node", "eslint-import-resolver-typescript", @@ -90,6 +91,7 @@ ], "ignorePaths": [ "docs", + ".dry-aged-deps.json", ".eslintignore", ".eslintrc-json.json", ".eslintrc.json", @@ -101,7 +103,6 @@ ".github/workflows/release.yml", ".github/workflows/upgrade-main.yml", ".gitignore", - ".mergify.yml", ".npmignore", ".prettierignore", ".prettierrc.json", diff --git a/.dry-aged-deps.json b/.dry-aged-deps.json new file mode 100644 index 0000000..ae79709 --- /dev/null +++ b/.dry-aged-deps.json @@ -0,0 +1,24 @@ +{ + "exclude": { + "@types/jest": "Pinned to jest 27.x; upgrade requires jest 29+ migration", + "cspell": "Major version upgrade; requires compatibility testing with current config", + "eslint": "Pinned to ^8; upgrade to 9+ requires flat config migration and plugin compatibility", + "eslint-config-prettier": "Major version upgrade; blocked by eslint 8.x constraint", + "eslint-import-resolver-node": "Pinned by eslint-plugin-import compatibility", + "eslint-import-resolver-typescript": "Major version upgrade; blocked by eslint 8.x constraint", + "eslint-plugin-import": "Pinned by eslint 8.x compatibility", + "eslint-plugin-no-secrets": "Major version upgrade; blocked by eslint 8.x constraint", + "eslint-plugin-prettier": "Major version upgrade; blocked by eslint 8.x constraint", + "eslint-plugin-unicorn": "Major version upgrade; blocked by eslint 8.x constraint", + "http-status-codes": "Used only in tests; minor update with no security impact", + "husky": "Major version upgrade; requires migration to new config format", + "jest": "Pinned to ^27 by projen; upgrade requires projen and ts-jest migration", + "jest-junit": "Major version upgrade; blocked by jest 27.x constraint", + "npm-check-updates": "Major version upgrade; used only for maintenance scripts", + "prettier": "Major version upgrade; may cause formatting changes across codebase", + "projen": "Pinned to ^0.58; upgrade may cause breaking changes to project config", + "ts-jest": "Pinned to jest 27.x; upgrade requires jest migration", + "ts-node": "Minor update; low priority with no security impact", + "typescript": "Major version upgrade; requires codebase compatibility verification" + } +} diff --git a/.eslintignore b/.eslintignore index 2dc2f32..4ad7ddf 100644 --- a/.eslintignore +++ b/.eslintignore @@ -15,7 +15,6 @@ .husky/commit-msg .husky/pre-commit .husky/pre-push -.mergify.yml .npmignore .prettierignore .prettierrc.json diff --git a/.eslintrc.json b/.eslintrc.json index a2e833e..0b7eba6 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -208,7 +208,6 @@ ".github/workflows/release.yml", ".github/workflows/upgrade-main.yml", ".gitignore", - ".mergify.yml", ".npmignore", ".prettierignore", ".prettierrc.json", diff --git a/.gitattributes b/.gitattributes index ee0304a..1f3b110 100644 --- a/.gitattributes +++ b/.gitattributes @@ -17,7 +17,6 @@ /.husky/commit-msg linguist-generated /.husky/pre-commit linguist-generated /.husky/pre-push linguist-generated -/.mergify.yml linguist-generated /.npmignore linguist-generated /.prettierignore linguist-generated /.prettierrc.json linguist-generated diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 03d6f68..33c0f94 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ jobs: CI: "true" steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} @@ -23,6 +23,8 @@ jobs: run: yarn install --check-files - name: build run: npx projen build + - name: Check for outdated dependencies + run: npx dry-aged-deps --check - id: self_mutation name: Find mutations run: |- @@ -30,7 +32,7 @@ jobs: git diff --staged --patch --exit-code > .repo.patch || echo "::set-output name=self_mutation_happened::true" - if: steps.self_mutation.outputs.self_mutation_happened name: Upload patch - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: .repo.patch path: .repo.patch @@ -48,13 +50,13 @@ jobs: if: always() && needs.build.outputs.self_mutation_happened && !(github.event.pull_request.head.repo.full_name != github.repository) steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: token: ${{ secrets.PROJEN_GITHUB_TOKEN }} ref: ${{ github.event.pull_request.head.ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} - name: Download patch - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: .repo.patch path: ${{ runner.temp }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 802ca24..3bd09cd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ jobs: CI: "true" steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set git identity @@ -33,7 +33,7 @@ jobs: run: echo ::set-output name=latest_commit::"$(git ls-remote origin -h ${{ github.ref }} | cut -f1)" - name: Upload artifact if: ${{ steps.git_remote.outputs.latest_commit == github.sha }} - uses: actions/upload-artifact@v2.1.1 + uses: actions/upload-artifact@v4 with: name: build-artifact path: dist @@ -45,11 +45,11 @@ jobs: contents: write if: needs.release.outputs.latest_commit == github.sha steps: - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 14.x - name: Download build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: build-artifact path: dist @@ -67,11 +67,11 @@ jobs: contents: read if: needs.release.outputs.latest_commit == github.sha steps: - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 14.x - name: Download build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: build-artifact path: dist diff --git a/.github/workflows/upgrade-main.yml b/.github/workflows/upgrade-main.yml index af1c1cd..5bed630 100644 --- a/.github/workflows/upgrade-main.yml +++ b/.github/workflows/upgrade-main.yml @@ -15,7 +15,7 @@ jobs: patch_created: ${{ steps.create_patch.outputs.patch_created }} steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: main - name: Install dependencies @@ -29,7 +29,7 @@ jobs: git diff --staged --patch --exit-code > .repo.patch || echo "::set-output name=patch_created::true" - if: steps.create_patch.outputs.patch_created name: Upload patch - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: .repo.patch path: .repo.patch @@ -43,12 +43,12 @@ jobs: if: ${{ needs.upgrade.outputs.patch_created }} steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: token: ${{ secrets.PROJEN_GITHUB_TOKEN }} ref: main - name: Download patch - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: .repo.patch path: ${{ runner.temp }} diff --git a/.gitignore b/.gitignore index 73779e3..78d268d 100644 --- a/.gitignore +++ b/.gitignore @@ -39,7 +39,6 @@ junit.xml /dist/changelog.md /dist/version.txt !/.github/workflows/release.yml -!/.mergify.yml !/.github/workflows/upgrade-main.yml !/.github/pull_request_template.md !/.prettierignore diff --git a/.husky/pre-push b/.husky/pre-push index f3e5d85..82f2bab 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -1,4 +1,5 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" npm run test -npm run eslint \ No newline at end of file +npm run eslint +npx dry-aged-deps --check \ No newline at end of file diff --git a/.mergify.yml b/.mergify.yml deleted file mode 100644 index eddac7d..0000000 --- a/.mergify.yml +++ /dev/null @@ -1,23 +0,0 @@ -# ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen". - -queue_rules: - - name: default - conditions: - - "#approved-reviews-by>=1" - - -label~=(do-not-merge) - - status-success=build -pull_request_rules: - - name: Automatic merge on approval and successful build - actions: - delete_head_branch: {} - queue: - method: squash - name: default - commit_message_template: |- - {{ title }} (#{{ number }}) - - {{ body }} - conditions: - - "#approved-reviews-by>=1" - - -label~=(do-not-merge) - - status-success=build diff --git a/.npmignore b/.npmignore index 77227ac..ad0995b 100644 --- a/.npmignore +++ b/.npmignore @@ -5,7 +5,6 @@ junit.xml /coverage/ /dist/changelog.md /dist/version.txt -/.mergify.yml /test/ /tsconfig.dev.json /src/ diff --git a/.project-words.txt b/.project-words.txt index f7db663..d9e7a4e 100644 --- a/.project-words.txt +++ b/.project-words.txt @@ -1,2 +1,4 @@ Hubber deps +mergify +yarnrc diff --git a/.projen/deps.json b/.projen/deps.json index b7f7044..9d103f5 100644 --- a/.projen/deps.json +++ b/.projen/deps.json @@ -39,6 +39,10 @@ "name": "cspell", "type": "build" }, + { + "name": "dry-aged-deps", + "type": "build" + }, { "name": "eslint-config-prettier", "type": "build" diff --git a/.projen/files.json b/.projen/files.json index 9210305..259ecd7 100644 --- a/.projen/files.json +++ b/.projen/files.json @@ -16,7 +16,6 @@ ".husky/commit-msg", ".husky/pre-commit", ".husky/pre-push", - ".mergify.yml", ".npmignore", ".prettierignore", ".prettierrc.json", diff --git a/.projen/tasks.json b/.projen/tasks.json index 1c10b22..f3dc807 100644 --- a/.projen/tasks.json +++ b/.projen/tasks.json @@ -129,7 +129,7 @@ "exec": "mkdir -p dist/js" }, { - "exec": "mv $(npm pack) dist/js/" + "exec": "npm pack --pack-destination dist/js" } ] }, diff --git a/.projenrc.ts b/.projenrc.ts index a6dec21..db04894 100644 --- a/.projenrc.ts +++ b/.projenrc.ts @@ -39,6 +39,7 @@ const project = new TypeScriptProject({ "http-status-codes", "@types/http-status-codes", "@mountainpass/cool-bits-for-projen", + "dry-aged-deps", ] /* Build dependencies for this module. */, keywords: ["problem-details", "rfc7807"], defaultReleaseBranch: "main", @@ -63,6 +64,7 @@ const project = new TypeScriptProject({ secret: "GITHUB_TOKEN", }, githubOptions: { + mergify: false, pullRequestLintOptions: { semanticTitleOptions: { types: [ @@ -83,12 +85,99 @@ const project = new TypeScriptProject({ }, }); -new Recommended(project, { - cSpellOptions: { language: "en-GB", ignorePaths: ["docs"] }, +const recommended = new Recommended(project, { + cSpellOptions: { + language: "en-GB", + ignorePaths: ["docs", ".dry-aged-deps.json"], + }, }); +// Add dry-aged-deps check to the pre-push hook +recommended.husky.addHook("pre-push", "npx dry-aged-deps --check"); + new CodeOfConduct(project, { contactMethod: "tom@mountain-pass.com.au" }); +// Fix npm pack command for newer npm versions +const packageTask = project.tasks.tryFind("package")!; +packageTask.reset(); +packageTask.exec("mkdir -p dist/js"); +packageTask.exec("npm pack --pack-destination dist/js"); + +// Add dry-aged-deps check to the build workflow +project.buildWorkflow?.addPostBuildSteps({ + name: "Check for outdated dependencies", + run: "npx dry-aged-deps --check", +}); + +// Upgrade deprecated GitHub Actions from v2/v3 to v4 +const buildWorkflow = project.github?.tryFindWorkflow("build"); +if (buildWorkflow?.file) { + buildWorkflow.file.addOverride( + "jobs.build.steps.0.uses", + "actions/checkout@v4" + ); + buildWorkflow.file.addOverride( + "jobs.build.steps.5.uses", + "actions/upload-artifact@v4" + ); + buildWorkflow.file.addOverride( + "jobs.self-mutation.steps.0.uses", + "actions/checkout@v4" + ); + buildWorkflow.file.addOverride( + "jobs.self-mutation.steps.1.uses", + "actions/download-artifact@v4" + ); +} + +const releaseWorkflow = project.github?.tryFindWorkflow("release"); +if (releaseWorkflow?.file) { + releaseWorkflow.file.addOverride( + "jobs.release.steps.0.uses", + "actions/checkout@v4" + ); + releaseWorkflow.file.addOverride( + "jobs.release.steps.5.uses", + "actions/upload-artifact@v4" + ); + releaseWorkflow.file.addOverride( + "jobs.release_github.steps.0.uses", + "actions/setup-node@v4" + ); + releaseWorkflow.file.addOverride( + "jobs.release_github.steps.1.uses", + "actions/download-artifact@v4" + ); + releaseWorkflow.file.addOverride( + "jobs.release_npm.steps.0.uses", + "actions/setup-node@v4" + ); + releaseWorkflow.file.addOverride( + "jobs.release_npm.steps.1.uses", + "actions/download-artifact@v4" + ); +} + +const upgradeWorkflow = project.github?.tryFindWorkflow("upgrade-main"); +if (upgradeWorkflow?.file) { + upgradeWorkflow.file.addOverride( + "jobs.upgrade.steps.0.uses", + "actions/checkout@v4" + ); + upgradeWorkflow.file.addOverride( + "jobs.upgrade.steps.4.uses", + "actions/upload-artifact@v4" + ); + upgradeWorkflow.file.addOverride( + "jobs.pr.steps.0.uses", + "actions/checkout@v4" + ); + upgradeWorkflow.file.addOverride( + "jobs.pr.steps.1.uses", + "actions/download-artifact@v4" + ); +} + gitHubber.addToProject(project); npmReleaser.addToProject(project); organisational.addToProject(project); diff --git a/.yarnrc b/.yarnrc new file mode 100644 index 0000000..4f14322 --- /dev/null +++ b/.yarnrc @@ -0,0 +1 @@ +--ignore-engines true diff --git a/package.json b/package.json index e4d8610..37c8cfe 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@typescript-eslint/eslint-plugin": "^5", "@typescript-eslint/parser": "^5", "cspell": "*", + "dry-aged-deps": "^2.6.0", "eslint": "^8", "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-node": "^0.3.6", @@ -132,6 +133,7 @@ }, "types": "lib/index.d.ts", "contributors": [ + "Claude ", "Tom Howard ", "dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>" ], diff --git a/yarn.lock b/yarn.lock index 4a37d87..a03aa8d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2449,6 +2449,11 @@ dotgitignore@^2.1.0: find-up "^3.0.0" minimatch "^3.0.4" +dry-aged-deps@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/dry-aged-deps/-/dry-aged-deps-2.6.0.tgz#d011e791bdc3b795f95660716ab2c65b8ca39246" + integrity sha512-neznE/c94RF2yOV7O3UXbXEL0Ohp6IX8T73h4t03+keCYXLmRIT/yhjGZh8IIvL75JN+HDyOoQQGvIIEvU4GSg== + duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"