diff --git a/.github/workflows/scripts/validate-redirects.js b/.github/workflows/scripts/validate-redirects.js new file mode 100644 index 00000000000..de89c1e3802 --- /dev/null +++ b/.github/workflows/scripts/validate-redirects.js @@ -0,0 +1,58 @@ +module.exports = { + invalidRedirects: () => { + const Ajv = require('ajv'); + const redirects = require('../../../redirects.json'); + const ajv = new Ajv(); + + const schema = { + type: 'array', + items: { + type: 'object', + required: ['source', 'target', 'status'], + properties: { + source: { + description: 'The address the user requested.', + type: 'string', + pattern: '^/' + }, + target: { + description: + 'The address that actually serves the content that the user sees', + type: 'string', + pattern: '^[(https)(/)]' + }, + status: { + description: + 'Types include a permanent redirect (301), a temporary redirect (302), a rewrite (200), or not found (404).', + type: 'string', + pattern: '^[0-5-]+$' + } + } + } + }; + + const errors = []; + const validate = ajv.compile(schema); + + const validateEntries = (redirects) => { + const valid = validate(redirects); + + if (!valid) { + const error = validate.errors[0]; + const invalidEntry = + JSON.stringify(redirects[error.instancePath.slice(1, -7)]); + const loc = error.schemaPath.slice(error.schemaPath.indexOf('properties') + 11, -8); + const errorMessage = '\n\n' + 'INVALID ENTRY: Please correct the error in the "' + loc +'" property of the following entry: \n' + invalidEntry + '\n' + 'ERROR MESSAGE: ' + error.message; + errors.push(errorMessage); + + validateEntries(redirects.splice(parseInt(error.instancePath.slice(1, -7)) + 1)); + + } + } + validateEntries(redirects); + + return errors; + } +} + + diff --git a/.github/workflows/validate_redirects.yml b/.github/workflows/validate_redirects.yml new file mode 100644 index 00000000000..e37598b26c2 --- /dev/null +++ b/.github/workflows/validate_redirects.yml @@ -0,0 +1,32 @@ +name: Validate Redirects +on: + pull_request: + branches: [main] + types: [opened, synchronize] +env: + BUILD_DIR: 'client/www/next-build' +permissions: + contents: read +jobs: + ValidateRedirects: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + - name: Setup Node.js 20.x + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: 20.x + - name: Install Dependencies + run: yarn + - name: Validate redirects + id: redirects + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + result-encoding: string + script: | + const { invalidRedirects } = require('./.github/workflows/scripts/validate-redirects.js'); + return await invalidRedirects(); + - name: Fail if any invalid redirects have been found + if: ${{ steps.redirects.outputs.result }} + run: exit 1 && echo ${{ steps.redirects.outputs.result }} diff --git a/package.json b/package.json index 492baeac11c..cb13c85ffaf 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@aws-amplify/amplify-cli-core": "^4.3.8", "@aws-amplify/ui-react": "^6.1.12", "@docsearch/react": "3", + "ajv": "^8.16.0", "aws-amplify": "^6.0.9", "next": "^14.2.3", "next-image-export-optimizer": "^1.8.3", diff --git a/redirects.json b/redirects.json index 9d74a7b3294..1655fdaae20 100644 --- a/redirects.json +++ b/redirects.json @@ -3011,7 +3011,7 @@ }, { "source": "/lib/client-configuration/configuring-amplify-categories/q/platform/react-native/", - "target": "react-native/tools/libraries/configure-categories/", + "target": "/react-native/tools/libraries/configure-categories/", "status": "301" }, { diff --git a/yarn.lock b/yarn.lock index cf335895a30..9afbdd468d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3547,6 +3547,16 @@ ajv@^8.0.1: require-from-string "^2.0.2" uri-js "^4.2.2" +ajv@^8.16.0: + version "8.16.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.16.0.tgz#22e2a92b94f005f7e0f9c9d39652ef0b8f6f0cb4" + integrity sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw== + dependencies: + fast-deep-equal "^3.1.3" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.4.1" + algoliasearch@^4.19.1: version "4.22.1" resolved "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.22.1.tgz" @@ -11493,7 +11503,7 @@ upper-case@^2.0.2: dependencies: tslib "^2.0.3" -uri-js@^4.2.2: +uri-js@^4.2.2, uri-js@^4.4.1: version "4.4.1" resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==