diff --git a/.github/workflows/check_for_broken_links.yml b/.github/workflows/check_for_broken_links.yml index f03377ccafc..181c6a1458b 100644 --- a/.github/workflows/check_for_broken_links.yml +++ b/.github/workflows/check_for_broken_links.yml @@ -32,7 +32,7 @@ jobs: role-to-assume: arn:aws:iam::464149486631:role/github_action_read_slack_webhook_url aws-region: us-west-2 - name: Read secrets from AWS Secrets Manager into environment variables - uses: aws-actions/aws-secretsmanager-get-secrets@ff26a0aa6bd4dd5e51326b5afb3f5f6874c958c7 # v2.0.3 + uses: aws-actions/aws-secretsmanager-get-secrets@98c2d6bf1dd67c2575fa2bb14294aa64103d426c # v2.0.5 with: secret-ids: | SLACK_WEBHOOK_URL 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/Readme.md b/Readme.md index ad7ad7438d7..4610e6201fc 100644 --- a/Readme.md +++ b/Readme.md @@ -175,7 +175,7 @@ let mut a = String::from("a"); Videos can be added using the `