From 853462cc086dda7c10293953d28bb031a337c27a Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Tue, 23 Aug 2022 12:36:27 -0400 Subject: [PATCH 1/8] Add URL test action --- .github/workflows/test.yml | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..9350c004 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,38 @@ +name: test + +on: + pull_request: + branches: [master] + push: + branches: [master] + +jobs: + web-urls: + name: Test URLs linked to by jellyfin-web + runs-on: ubuntu-latest + + strategy: + fail-fast: true + matrix: + url: + - /docs/general/administration/hardware-acceleration.html + + steps: + - name: Check out Git repository + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2 + + - name: Set up Node.js + uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3.4.1 + with: + node-version: 16 + check-latest: true + cache: npm + + - name: Build and start test server + run: | + npm ci --no-audit + npm run build + npm run serve + + - name: Test URL + run: curl --fail --location --silent --output /dev/null ${{ matrix.url }} From c8c3fae1c2d1535d6cc0160601bb2cdbe37450af Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Tue, 23 Aug 2022 12:41:52 -0400 Subject: [PATCH 2/8] Fork test server start --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9350c004..c9012f79 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,7 +32,7 @@ jobs: run: | npm ci --no-audit npm run build - npm run serve + npm run serve & - name: Test URL run: curl --fail --location --silent --output /dev/null ${{ matrix.url }} From 9b935f06832ff30dfebde2ef85875c1f8cfe81ff Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Tue, 23 Aug 2022 12:50:02 -0400 Subject: [PATCH 3/8] Fix test URLs --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c9012f79..9371a2d5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,4 +35,4 @@ jobs: npm run serve & - name: Test URL - run: curl --fail --location --silent --output /dev/null ${{ matrix.url }} + run: curl --fail --location --silent --output /dev/null http://localhost:3000${{ matrix.url }} From 00a02e7e3b27f009774f5b04f9aac76ff7e6de73 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Tue, 23 Aug 2022 12:57:29 -0400 Subject: [PATCH 4/8] Add test URL --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9371a2d5..34ef56b6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,6 +15,7 @@ jobs: fail-fast: true matrix: url: + - /docs/getting-started # FIXME: This should be removed. Just testing an existing URL. - /docs/general/administration/hardware-acceleration.html steps: From 6693a4359704260250f123e54e8eaba9e0bae503 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Tue, 23 Aug 2022 23:15:45 -0400 Subject: [PATCH 5/8] Add node script for url testing --- .github/workflows/test.yml | 9 +- package-lock.json | 173 +++++++++++++++++++++++++--- package.json | 4 +- scripts/check-urls.mjs | 47 ++++++++ scripts/data/jellyfin-web-urls.json | 22 ++++ 5 files changed, 230 insertions(+), 25 deletions(-) create mode 100644 scripts/check-urls.mjs create mode 100644 scripts/data/jellyfin-web-urls.json diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 34ef56b6..112568df 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,13 +11,6 @@ jobs: name: Test URLs linked to by jellyfin-web runs-on: ubuntu-latest - strategy: - fail-fast: true - matrix: - url: - - /docs/getting-started # FIXME: This should be removed. Just testing an existing URL. - - /docs/general/administration/hardware-acceleration.html - steps: - name: Check out Git repository uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2 @@ -36,4 +29,4 @@ jobs: npm run serve & - name: Test URL - run: curl --fail --location --silent --output /dev/null http://localhost:3000${{ matrix.url }} + run: npm run test:web-urls diff --git a/package-lock.json b/package-lock.json index 9ba6aa9f..280e78f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,6 +39,7 @@ "eslint-plugin-promise": "6.0.0", "eslint-plugin-react": "7.30.1", "eslint-plugin-react-hooks": "4.6.0", + "node-fetch": "^3.2.10", "prettier": "2.7.1", "typescript": "4.7.4", "typescript-plugin-css-modules": "3.4.0" @@ -9527,6 +9528,25 @@ "node-fetch": "2.6.7" } }, + "node_modules/cross-fetch/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -9881,6 +9901,15 @@ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", + "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -12093,6 +12122,29 @@ "node": ">=0.4.0" } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -12343,6 +12395,18 @@ "node": ">=6" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -14741,6 +14805,25 @@ "tslib": "^2.0.3" } }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, "node_modules/node-emoji": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", @@ -14750,22 +14833,21 @@ } }, "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.10.tgz", + "integrity": "sha512-MhuzNwdURnZ1Cp4XTazr69K0BTizsBroX7Zx3UgDSVcZYKF/6p0CBe4EUb/hLqmzVhl0UpYfgRljQ4yxE+iCxA==", + "dev": true, "dependencies": { - "whatwg-url": "^5.0.0" + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" }, "engines": { - "node": "4.x || >=6.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" } }, "node_modules/node-forge": { @@ -19930,6 +20012,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -27570,6 +27661,16 @@ "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", "requires": { "node-fetch": "2.6.7" + }, + "dependencies": { + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + } } }, "cross-spawn": { @@ -27819,6 +27920,12 @@ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true }, + "data-uri-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", + "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", + "dev": true + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -29446,6 +29553,16 @@ "xml-js": "^1.6.11" } }, + "fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "requires": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -29615,6 +29732,15 @@ } } }, + "formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "requires": { + "fetch-blob": "^3.1.2" + } + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -31345,6 +31471,12 @@ "tslib": "^2.0.3" } }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true + }, "node-emoji": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", @@ -31354,11 +31486,14 @@ } }, "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.10.tgz", + "integrity": "sha512-MhuzNwdURnZ1Cp4XTazr69K0BTizsBroX7Zx3UgDSVcZYKF/6p0CBe4EUb/hLqmzVhl0UpYfgRljQ4yxE+iCxA==", + "dev": true, "requires": { - "whatwg-url": "^5.0.0" + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" } }, "node-forge": { @@ -35048,6 +35183,12 @@ "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==" }, + "web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "dev": true + }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/package.json b/package.json index 2911dd36..c49007a0 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "serve": "docusaurus serve", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", - "lint": "eslint --ext .ts,.js,.json,.jsx,.tsx ." + "lint": "eslint --ext .ts,.js,.json,.jsx,.tsx .", + "test:web-urls": "node ./scripts/check-urls.mjs ./scripts/data/jellyfin-web-urls.json" }, "dependencies": { "@docusaurus/core": "2.0.1", @@ -61,6 +62,7 @@ "eslint-plugin-promise": "6.0.0", "eslint-plugin-react": "7.30.1", "eslint-plugin-react-hooks": "4.6.0", + "node-fetch": "^3.2.10", "prettier": "2.7.1", "typescript": "4.7.4", "typescript-plugin-css-modules": "3.4.0" diff --git a/scripts/check-urls.mjs b/scripts/check-urls.mjs new file mode 100644 index 00000000..aa10a273 --- /dev/null +++ b/scripts/check-urls.mjs @@ -0,0 +1,47 @@ +import fetch from 'node-fetch'; +import * as fs from 'node:fs/promises'; +import path from 'node:path'; + +// 1xx, 2xx, and 3xx http status do not indicate errors +const isErrorStatus = (status) => Math.floor(status / 100) > 3; + +// A path parameter is required to provide a JSON file containing a list of URLs to check +const [, , pathArg] = process.argv; +if (!pathArg) { + throw new Error('path is required'); +} +const filePath = path.resolve(process.cwd(), pathArg); +const urls = JSON.parse(await fs.readFile(filePath)); + +// The host to check can be overriden by an environment variable +const HOST = process.env.CHECK_URL_HOST || 'http://localhost:3000'; + +// List of any failed requests +const failures = []; + +await Promise.allSettled( + urls.map(async (url) => { + console.log(`Checking URL >> ${HOST}${url}`); + + try { + const response = await fetch(`${HOST}${url}`); + + if (isErrorStatus(response.status)) { + failures.push({ + url, + error: new Error(`HTTP Error: ${response.status} ${response.statusText}`), + response + }); + } + } catch (error) { + failures.push({ url, error }); + } + }) +); + +if (failures.length === 0) { + console.log('All URLs successful'); +} else { + console.error('The following errors were encountered', failures); + process.exit(1); +} diff --git a/scripts/data/jellyfin-web-urls.json b/scripts/data/jellyfin-web-urls.json new file mode 100644 index 00000000..334cd994 --- /dev/null +++ b/scripts/data/jellyfin-web-urls.json @@ -0,0 +1,22 @@ +[ + "/docs/general/administration/hardware-acceleration.html", + "/docs/general/contributing/index.html", + "/docs/general/networking/dlna.html", + "/docs/general/networking/index.html", + "/docs/general/quick-start.html", + "/docs/general/server/devices.html", + "/docs/general/server/libraries.html", + "/docs/general/server/live-tv/index.html", + "/docs/general/server/live-tv/setup-guide.html", + "/docs/general/server/media/books.html", + "/docs/general/server/media/external-files.html", + "/docs/general/server/media/movies.html", + "/docs/general/server/media/music.html", + "/docs/general/server/media/shows.html", + "/docs/general/server/notifications.html", + "/docs/general/server/plugins/index.html", + "/docs/general/server/settings.html", + "/docs/general/server/tasks.html", + "/docs/general/server/transcoding.html", + "/docs/general/server/users/adding-managing-users.html" +] From a8e184ffbd14a6ce1b3babfa63295dd77f346a96 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 24 Aug 2022 00:27:31 -0400 Subject: [PATCH 6/8] Add more url tests --- .github/workflows/test.yml | 14 +++++-- package.json | 2 + scripts/check-urls.mjs | 4 +- scripts/data/jellyfin-blog-urls.json | 39 +++++++++++++++++ scripts/data/jellyfin-docs-urls.json | 63 ++++++++++++++++++++++++++++ 5 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 scripts/data/jellyfin-blog-urls.json create mode 100644 scripts/data/jellyfin-docs-urls.json diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 112568df..958df629 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,10 +7,18 @@ on: branches: [master] jobs: - web-urls: - name: Test URLs linked to by jellyfin-web + test-urls: + name: Test URLs runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + command: + - test:blog-urls + - test:docs-urls + - test:web-urls + steps: - name: Check out Git repository uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2 @@ -29,4 +37,4 @@ jobs: npm run serve & - name: Test URL - run: npm run test:web-urls + run: npm run ${{ matrix.command }} diff --git a/package.json b/package.json index c49007a0..3c355d34 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,8 @@ "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", "lint": "eslint --ext .ts,.js,.json,.jsx,.tsx .", + "test:blog-urls": "node ./scripts/check-urls.mjs ./scripts/data/jellyfin-blog-urls.json", + "test:docs-urls": "node ./scripts/check-urls.mjs ./scripts/data/jellyfin-docs-urls.json", "test:web-urls": "node ./scripts/check-urls.mjs ./scripts/data/jellyfin-web-urls.json" }, "dependencies": { diff --git a/scripts/check-urls.mjs b/scripts/check-urls.mjs index aa10a273..34baffb3 100644 --- a/scripts/check-urls.mjs +++ b/scripts/check-urls.mjs @@ -40,8 +40,8 @@ await Promise.allSettled( ); if (failures.length === 0) { - console.log('All URLs successful'); + console.log('🚀 All URLs successful'); } else { - console.error('The following errors were encountered', failures); + console.error(['❌ The following URLs failed', ...failures.map((failure) => `${HOST}${failure.url}`)].join('\n')); process.exit(1); } diff --git a/scripts/data/jellyfin-blog-urls.json b/scripts/data/jellyfin-blog-urls.json new file mode 100644 index 00000000..45a6fbb0 --- /dev/null +++ b/scripts/data/jellyfin-blog-urls.json @@ -0,0 +1,39 @@ +[ + "/", + "/posts/android-tv-14/", + "/posts/", + "/posts/roku-v1.5.0/", + "/posts/webos-july2022/", + "/posts/jellyfin-10-8-0/", + "/posts/ios-update-150/", + "/posts/android-tv-13/", + "/posts/android-v2.4.0/", + "/posts/android-tv-12/", + "/posts/android-v2.3.0/", + "/posts/android-betas/", + "/posts/client-jmp/", + "/posts/a-note-about-privacy-and-expo/", + "/posts/mirrorbits-cdn/", + "/posts/android-on-fdroid/", + "/posts/jellyfin-apt-key/", + "/posts/android-v2.1.0/", + "/posts/android-next/", + "/posts/client-videotape/", + "/posts/jellyfin-10-6-0/", + "/posts/plugin-updates/", + "/posts/packaging-updates/", + "/posts/client-infuse/", + "/posts/jellyfin-xbox/", + "/clients/", + "/posts/jellyfin-10-5-0/", + "/posts/kodi-0-5-0/", + "/posts/client-mpv/", + "/posts/android-tv-11/", + "/posts/jellyfin-in-2019/", + "/posts/welcome/", + "/contact/", + "/downloads/", + "/contribute/", + "/categories/", + "/tags/" +] diff --git a/scripts/data/jellyfin-docs-urls.json b/scripts/data/jellyfin-docs-urls.json new file mode 100644 index 00000000..43b2b5f7 --- /dev/null +++ b/scripts/data/jellyfin-docs-urls.json @@ -0,0 +1,63 @@ +[ + "/docs/general/about.html", + "/docs/general/administration/building.html", + "/docs/general/administration/configuration.html", + "/docs/general/administration/hardware-acceleration.html", + "/docs/general/administration/install/synology.html", + "/docs/general/administration/installing.html", + "/docs/general/administration/migrate.html", + "/docs/general/administration/troubleshooting.html", + "/docs/general/clients/codec-support.html", + "/docs/general/clients/css-customization.html", + "/docs/general/clients/index.html", + "/docs/general/clients/kodi.html", + "/docs/general/clients/mopidy.html", + "/docs/general/clients/web-config.html", + "/docs/general/community-standards.html", + "/docs/general/contributing/branding.html", + "/docs/general/contributing/development.html", + "/docs/general/contributing/index.html", + "/docs/general/contributing/issues.html", + "/docs/general/contributing/release-procedure.html", + "/docs/general/contributing/source-tree.html", + "/docs/general/faq.html", + "/docs/general/getting-help.html", + "/docs/general/networking/apache.html", + "/docs/general/networking/caddy.html", + "/docs/general/networking/dlna.html", + "/docs/general/networking/fail2ban.html", + "/docs/general/networking/haproxy.html", + "/docs/general/networking/index.html", + "/docs/general/networking/letsencrypt.html", + "/docs/general/networking/monitoring.html", + "/docs/general/networking/nginx.html", + "/docs/general/networking/traefik.html", + "/docs/general/networking/traefik2.html", + "/docs/general/quick-start.html", + "/docs/general/server/devices.html", + "/docs/general/server/libraries.html", + "/docs/general/server/live-tv/index.html", + "/docs/general/server/live-tv/post-process.html", + "/docs/general/server/live-tv/setup-guide.html", + "/docs/general/server/media/books.html", + "/docs/general/server/media/comics.html", + "/docs/general/server/media/external-files.html", + "/docs/general/server/media/internet-radio.html", + "/docs/general/server/media/movies.html", + "/docs/general/server/media/music.html", + "/docs/general/server/media/shows.html", + "/docs/general/server/notifications.html", + "/docs/general/server/plugins/index.html", + "/docs/general/server/plugins/open-subtitles.html", + "/docs/general/server/plugins/tvheadend.html", + "/docs/general/server/quick-connect.html", + "/docs/general/server/settings.html", + "/docs/general/server/storage.html", + "/docs/general/server/tasks.html", + "/docs/general/server/transcoding.html", + "/docs/general/server/users/adding-managing-users.html", + "/docs/general/server/users/index.html", + "/docs/general/style-guides/index.html", + "/docs/general/style-guides/javascript.html", + "/docs/index.html" +] From fb93d992232cda15c521ee761a80ddd70a6a0b07 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 24 Aug 2022 01:22:15 -0400 Subject: [PATCH 7/8] Add redirects for categories and tags --- docusaurus.config.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docusaurus.config.js b/docusaurus.config.js index b5ce7982..cc821460 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -115,7 +115,13 @@ module.exports = { [ '@docusaurus/plugin-client-redirects', { - fromExtensions: ['html'] + fromExtensions: ['html'], + redirects: [ + { + from: ['/categories', '/tags'], + to: '/posts' + } + ] } ] ] From 3269432439360be0d5fae7fbb8bb3cfd96eea068 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 25 Aug 2022 10:05:24 -0400 Subject: [PATCH 8/8] Add warnings for known valid URLs --- scripts/check-urls.mjs | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/scripts/check-urls.mjs b/scripts/check-urls.mjs index 34baffb3..08cba632 100644 --- a/scripts/check-urls.mjs +++ b/scripts/check-urls.mjs @@ -5,6 +5,11 @@ import path from 'node:path'; // 1xx, 2xx, and 3xx http status do not indicate errors const isErrorStatus = (status) => Math.floor(status / 100) > 3; +// HACK: URLs containing periods are not handled correctly by the docusaurus test server currently. The following URLs +// return 404s even though they exist and work as expected on GH Pages. +const isProblematicUrl = (url) => + ['/posts/roku-v1.5.0/', '/posts/android-v2.4.0/', '/posts/android-v2.3.0/', '/posts/android-v2.1.0/'].includes(url); + // A path parameter is required to provide a JSON file containing a list of URLs to check const [, , pathArg] = process.argv; if (!pathArg) { @@ -18,6 +23,7 @@ const HOST = process.env.CHECK_URL_HOST || 'http://localhost:3000'; // List of any failed requests const failures = []; +const warnings = []; await Promise.allSettled( urls.map(async (url) => { @@ -27,11 +33,15 @@ await Promise.allSettled( const response = await fetch(`${HOST}${url}`); if (isErrorStatus(response.status)) { - failures.push({ - url, - error: new Error(`HTTP Error: ${response.status} ${response.statusText}`), - response - }); + if (response.status === 404 && isProblematicUrl(url)) { + warnings.push({ url, response }); + } else { + failures.push({ + url, + error: new Error(`HTTP Error: ${response.status} ${response.statusText}`), + response + }); + } } } catch (error) { failures.push({ url, error }); @@ -39,9 +49,20 @@ await Promise.allSettled( }) ); -if (failures.length === 0) { - console.log('🚀 All URLs successful'); -} else { +if (warnings.length > 0) { + console.warn( + [ + '⚠ The following URLs returned 404s, but should have succeeded', + ...warnings.map((warning) => `${HOST}${warning.url}`) + ].join('\n') + ); +} + +if (failures.length > 0) { console.error(['❌ The following URLs failed', ...failures.map((failure) => `${HOST}${failure.url}`)].join('\n')); process.exit(1); } + +if (warnings.length === 0) { + console.log('🚀 All URLs successful'); +}