diff --git a/.github/workflows/database-backup-dev.yml b/.github/workflows/database-backup-dev.yml new file mode 100644 index 00000000..048c6d14 --- /dev/null +++ b/.github/workflows/database-backup-dev.yml @@ -0,0 +1,132 @@ +name: Database Backup + +permissions: + contents: read + +on: + workflow_call: + secrets: + CF_USER: + required: true + CF_PASSWORD: + required: true + CF_ORG: + required: true + PROJECT: + required: true + DATABASE_BACKUP_BASTION_NAME: + required: true + +jobs: + startBastion: + name: Start Bastion + runs-on: ubuntu-latest + if: github.ref_protected == true + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + - name: Set env + run: | + BRANCH=develop + CF_SPACE="dev" + + echo "BRANCH=${BRANCH}" | tee -a $GITHUB_ENV + echo "CF_SPACE=${CF_SPACE}" | tee -a $GITHUB_ENV + + - name: Install basic dependencies + run: ./scripts/pipeline/deb-basic-deps.sh + - name: Install Cloudfoundry CLI + run: ./scripts/pipeline/deb-cf-install.sh + - name: Cloud.gov login + env: + CF_USER: "${{ secrets.CF_USER }}" + CF_PASSWORD: "${{ secrets.CF_PASSWORD }}" + CF_ORG: "${{ secrets.CF_ORG }}" + PROJECT: "${{ secrets.PROJECT }}" + run: | + source ./scripts/pipeline/cloud-gov-login.sh + - name: Start Bastion + env: + PROJECT: "${{ secrets.PROJECT }}" + DATABASE_BACKUP_BASTION_NAME: "${{ secrets.DATABASE_BACKUP_BASTION_NAME }}" + run: | + cf start "${PROJECT}-${DATABASE_BACKUP_BASTION_NAME}-${CF_SPACE}" >/dev/null 2>&1 + ./scripts/pipeline/cloud-gov-wait-for-app-start.sh "${PROJECT}-${DATABASE_BACKUP_BASTION_NAME}-${CF_SPACE}" + backup-database: + runs-on: ubuntu-latest + continue-on-error: true + needs: startBastion + if: github.ref_protected == true + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + - name: Set env + run: | + BRANCH=develop + CF_SPACE="dev" + + echo "BRANCH=${BRANCH}" | tee -a $GITHUB_ENV + echo "CF_SPACE=${CF_SPACE}" | tee -a $GITHUB_ENV + + - name: Install basic dependencies + run: ./scripts/pipeline/deb-basic-deps.sh + - name: Install AWSCLI + run: ./scripts/pipeline/deb-awscli.sh + - name: Install MySQL Client + run: ./scripts/pipeline/deb-mysql-client-install.sh + - name: Install Cloudfoundry CLI + run: ./scripts/pipeline/deb-cf-install.sh + - name: Cloud.gov login + env: + CF_USER: "${{ secrets.CF_USER }}" + CF_PASSWORD: "${{ secrets.CF_PASSWORD }}" + CF_ORG: "${{ secrets.CF_ORG }}" + PROJECT: "${{ secrets.PROJECT }}" + run: | + source ./scripts/pipeline/cloud-gov-login.sh + - name: Backup Database + id: backup + shell: bash + env: + CF_USER: "${{ secrets.CF_USER }}" + CF_PASSWORD: "${{ secrets.CF_PASSWORD }}" + CF_ORG: "${{ secrets.CF_ORG }}" + PROJECT: "${{ secrets.PROJECT }}" + DATABASE_BACKUP_BASTION_NAME: "${{ secrets.DATABASE_BACKUP_BASTION_NAME }}" + run: | + export TIMESTAMP=$(date --utc +%FT%TZ | tr ':', '-') + source ./scripts/pipeline/database-backup.sh + stopBastion: + name: Stop Bastion + runs-on: ubuntu-latest + needs: backup-database + if: github.ref_protected == true && ${{ always() }} + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + - name: Set env + run: | + BRANCH=develop + CF_SPACE="dev" + + echo "BRANCH=${BRANCH}" | tee -a $GITHUB_ENV + echo "CF_SPACE=${CF_SPACE}" | tee -a $GITHUB_ENV + + - name: Install basic dependencies + run: ./scripts/pipeline/deb-basic-deps.sh + - name: Install Cloudfoundry CLI + run: ./scripts/pipeline/deb-cf-install.sh + - name: Cloud.gov login + env: + CF_USER: "${{ secrets.CF_USER }}" + CF_PASSWORD: "${{ secrets.CF_PASSWORD }}" + CF_ORG: "${{ secrets.CF_ORG }}" + PROJECT: "${{ secrets.PROJECT }}" + run: | + source ./scripts/pipeline/cloud-gov-login.sh + - name: Stop Bastion + env: + PROJECT: "${{ secrets.PROJECT }}" + DATABASE_BACKUP_BASTION_NAME: "${{ secrets.DATABASE_BACKUP_BASTION_NAME }}" + run: | + cf stop "${PROJECT}-${DATABASE_BACKUP_BASTION_NAME}-${CF_SPACE}" >/dev/null 2>&1 diff --git a/.github/workflows/database-restore-dev.yml b/.github/workflows/database-restore-dev.yml new file mode 100644 index 00000000..0970e9d9 --- /dev/null +++ b/.github/workflows/database-restore-dev.yml @@ -0,0 +1,141 @@ +name: Database Restore + +permissions: + contents: read + +on: + workflow_dispatch: + inputs: + database_file_override: + description: "Path on S3 bucket to a specific database file to restore." + required: false +jobs: + start-bastion: + name: Start Bastion + runs-on: ubuntu-latest + if: ${{ always() }} + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + - name: Set env.BRANCH + run: | + echo "BRANCH=$(echo $GITHUB_REF | cut -d'/' -f 3)" | tee -a $GITHUB_ENV + case ${BRANCH} in + develop) + CF_SPACE="dev" + ;; + main) + CF_SPACE="prod" + ;; + stage) + CF_SPACE="staging" + ;; + esac + echo "CF_SPACE=${CF_SPACE}" | tee -a $GITHUB_ENV + - name: Install basic dependancies + run: ./scripts/pipeline/deb-basic-deps.sh + - name: Install Cloudfoundry CLI + run: ./scripts/pipeline/deb-cf-install.sh + - name: Cloud.gov login + env: + CF_USER: "${{ secrets.CF_USER }}" + CF_PASSWORD: "${{ secrets.CF_PASSWORD }}" + CF_ORG: "${{ secrets.CF_ORG }}" + PROJECT: "${{ secrets.PROJECT }}" + run: source ./scripts/pipeline/cloud-gov-login.sh + - name: Start Bastion + env: + DATABASE_BACKUP_BASTION_NAME: "${{ secrets.DATABASE_BACKUP_BASTION_NAME }}" + PROJECT: "${{ secrets.PROJECT }}" + run: | + cf start "${PROJECT}-${DATABASE_BACKUP_BASTION_NAME}-${CF_SPACE}" >/dev/null 2>&1 + ./scripts/pipeline/cloud-gov-wait-for-app-start.sh "${PROJECT}-${DATABASE_BACKUP_BASTION_NAME}-${CF_SPACE}" + restore-database: + runs-on: ubuntu-latest + needs: start-bastion + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + - name: Set env.BRANCH + run: | + echo "BRANCH=$(echo $GITHUB_REF | cut -d'/' -f 3)" | tee -a $GITHUB_ENV + + case ${BRANCH} in + develop) + CF_SPACE="dev" + ;; + main) + CF_SPACE="prod" + ;; + stage) + CF_SPACE="staging" + ;; + esac + echo "CF_SPACE=${CF_SPACE}" | tee -a $GITHUB_ENV + - name: Install basic dependancies + run: ./scripts/pipeline/deb-basic-deps.sh + - name: Install AWSCLI + run: ./scripts/pipeline/awscli-install.sh + - name: Install MySQL Client + run: ./scripts/pipeline/deb-mysql-client-install.sh + - name: Install Cloudfoundry CLI + run: ./scripts/pipeline/deb-cf-install.sh + - name: Cloud.gov login + env: + CF_USER: "${{ secrets.CF_USER }}" + CF_PASSWORD: "${{ secrets.CF_PASSWORD }}" + CF_ORG: "${{ secrets.CF_ORG }}" + PROJECT: "${{ secrets.PROJECT }}" + run: source ./scripts/pipeline/cloud-gov-login.sh + - name: Restore database + shell: bash + env: + CF_USER: "${{ secrets.CF_USER }}" + CF_PASSWORD: "${{ secrets.CF_PASSWORD }}" + CF_ORG: "${{ secrets.CF_ORG }}" + PROJECT: "${{ secrets.PROJECT }}" + DATABASE_BACKUP_BASTION_NAME: "${{ secrets.DATABASE_BACKUP_BASTION_NAME }}" + run: | + export S3_FILE_PATH=${{ github.event.inputs.database_file_override }} + source ./scripts/pipeline/s3-backup-download.sh + source ./scripts/pipeline/database-restore.sh + source ./scripts/pipeline/cloud-gov-post-deploy.sh + stop-bastion: + name: Stop Bastion + runs-on: ubuntu-latest + needs: restore-database + if: ${{ always() }} + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + - name: Set env.BRANCH + run: | + echo "BRANCH=$(echo $GITHUB_REF | cut -d'/' -f 3)" | tee -a $GITHUB_ENV + case ${BRANCH} in + develop) + CF_SPACE="dev" + ;; + main) + CF_SPACE="prod" + ;; + stage) + CF_SPACE="staging" + ;; + esac + echo "CF_SPACE=${CF_SPACE}" | tee -a $GITHUB_ENV + - name: Install basic dependancies + run: ./scripts/pipeline/deb-basic-deps.sh + - name: Install Cloudfoundry CLI + run: ./scripts/pipeline/deb-cf-install.sh + - name: Cloud.gov login + env: + CF_USER: "${{ secrets.CF_USER }}" + CF_PASSWORD: "${{ secrets.CF_PASSWORD }}" + CF_ORG: "${{ secrets.CF_ORG }}" + PROJECT: "${{ secrets.PROJECT }}" + run: source ./scripts/pipeline/cloud-gov-login.sh + - name: Stop Bastion + env: + DATABASE_BACKUP_BASTION_NAME: "${{ secrets.DATABASE_BACKUP_BASTION_NAME }}" + PROJECT: "${{ secrets.PROJECT }}" + run: cf stop "${PROJECT}-${DATABASE_BACKUP_BASTION_NAME}-${CF_SPACE}" >/dev/null 2>&1 diff --git a/composer.json b/composer.json index 4eede2ef..a342b95b 100644 --- a/composer.json +++ b/composer.json @@ -26,9 +26,9 @@ "drupal/config_pages": "^2.19", "drupal/config_split": "^2.0", "drupal/content_moderation_notifications": "^3.8", - "drupal/core-composer-scaffold": "10.6.12", - "drupal/core-project-message": "10.6.12", - "drupal/core-recommended": "10.6.12", + "drupal/core-composer-scaffold": "10.6.14", + "drupal/core-project-message": "^10.6.14", + "drupal/core-recommended": "10.6.14", "drupal/database_ssl_check": "^2.0", "drupal/default_content": "^2.0@beta", "drupal/disable_user_1_edit": "^1.6", diff --git a/composer.lock b/composer.lock index 244fb65a..08c7d97a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a266544be647865b4261e1ea875b3b9a", + "content-hash": "cefb4e39e3991b7763a22dd8bf599e7a", "packages": [ { "name": "asm89/stack-cors", @@ -1948,16 +1948,16 @@ }, { "name": "drupal/core", - "version": "10.6.12", + "version": "10.6.14", "source": { "type": "git", "url": "https://github.com/drupal/core.git", - "reference": "87fd33ee009619bcd0a1679d6015c349f74dd977" + "reference": "d7476043e931569bd584982e4bdd453900ac1620" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core/zipball/87fd33ee009619bcd0a1679d6015c349f74dd977", - "reference": "87fd33ee009619bcd0a1679d6015c349f74dd977", + "url": "https://api.github.com/repos/drupal/core/zipball/d7476043e931569bd584982e4bdd453900ac1620", + "reference": "d7476043e931569bd584982e4bdd453900ac1620", "shasum": "" }, "require": { @@ -2107,13 +2107,13 @@ ], "description": "Drupal is an open source content management platform powering millions of websites and applications.", "support": { - "source": "https://github.com/drupal/core/tree/10.6.12" + "source": "https://github.com/drupal/core/tree/10.6.14" }, - "time": "2026-06-23T07:23:10+00:00" + "time": "2026-07-23T00:19:22+00:00" }, { "name": "drupal/core-composer-scaffold", - "version": "10.6.12", + "version": "10.6.14", "source": { "type": "git", "url": "https://github.com/drupal/core-composer-scaffold.git", @@ -2157,13 +2157,13 @@ "drupal" ], "support": { - "source": "https://github.com/drupal/core-composer-scaffold/tree/10.6.12" + "source": "https://github.com/drupal/core-composer-scaffold/tree/10.6.14" }, "time": "2024-08-22T14:31:30+00:00" }, { "name": "drupal/core-project-message", - "version": "10.6.12", + "version": "10.6.14", "source": { "type": "git", "url": "https://github.com/drupal/core-project-message.git", @@ -2204,16 +2204,16 @@ }, { "name": "drupal/core-recommended", - "version": "10.6.12", + "version": "10.6.14", "source": { "type": "git", "url": "https://github.com/drupal/core-recommended.git", - "reference": "d11d79225bf6f0ce2f17cd29daf96ec625ec5a63" + "reference": "d434d11aa1622471002566202deab6c309fd0606" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core-recommended/zipball/d11d79225bf6f0ce2f17cd29daf96ec625ec5a63", - "reference": "d11d79225bf6f0ce2f17cd29daf96ec625ec5a63", + "url": "https://api.github.com/repos/drupal/core-recommended/zipball/d434d11aa1622471002566202deab6c309fd0606", + "reference": "d434d11aa1622471002566202deab6c309fd0606", "shasum": "" }, "require": { @@ -2221,11 +2221,11 @@ "composer/semver": "~3.4.4", "doctrine/deprecations": "~1.1.5", "doctrine/lexer": "~2.1.1", - "drupal/core": "10.6.12", + "drupal/core": "10.6.14", "egulias/email-validator": "~4.0.4", - "guzzlehttp/guzzle": "~7.12.1", - "guzzlehttp/promises": "~2.5.0", - "guzzlehttp/psr7": "~2.12.1", + "guzzlehttp/guzzle": "~7.15.1", + "guzzlehttp/promises": "~2.5.1", + "guzzlehttp/psr7": "~2.13.0", "masterminds/html5": "~2.10.0", "mck89/peast": "~v1.17.4", "pear/archive_tar": "~1.6.0", @@ -2281,9 +2281,9 @@ ], "description": "Core and its dependencies with known-compatible minor versions. Require this project INSTEAD OF drupal/core.", "support": { - "source": "https://github.com/drupal/core-recommended/tree/10.6.12" + "source": "https://github.com/drupal/core-recommended/tree/10.6.14" }, - "time": "2026-06-23T07:23:10+00:00" + "time": "2026-07-23T00:19:22+00:00" }, { "name": "drupal/ctools", @@ -6598,22 +6598,22 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.12.3", + "version": "7.15.2", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "9aa17bcdd777ee31df9fc83c337ca4ca2340def3" + "reference": "744101956d78b7c1384d0cbf379db13e859167bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9aa17bcdd777ee31df9fc83c337ca4ca2340def3", - "reference": "9aa17bcdd777ee31df9fc83c337ca4ca2340def3", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/744101956d78b7c1384d0cbf379db13e859167bf", + "reference": "744101956d78b7c1384d0cbf379db13e859167bf", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^2.5", - "guzzlehttp/psr7": "^2.12.3", + "guzzlehttp/promises": "^2.5.1", + "guzzlehttp/psr7": "^2.13", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.5 || ^3.0", @@ -6625,8 +6625,8 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", - "guzzle/client-integration-tests": "3.0.2", - "guzzlehttp/test-server": "^0.5.1", + "guzzle/client-integration-tests": "3.0.3", + "guzzlehttp/test-server": "^0.7", "php-http/message-factory": "^1.1", "phpunit/phpunit": "^8.5.52 || ^9.6.34", "psr/log": "^1.1 || ^2.0 || ^3.0" @@ -6706,7 +6706,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.12.3" + "source": "https://github.com/guzzle/guzzle/tree/7.15.2" }, "funding": [ { @@ -6722,20 +6722,20 @@ "type": "tidelift" } ], - "time": "2026-06-23T15:29:02+00:00" + "time": "2026-07-26T23:23:20+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.5.0", + "version": "2.5.1", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "4360e982f87f5f258bf872d094647791db2f4c8e" + "reference": "9ad1e4fc607446a055b95870c7f668e93b5cff29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/4360e982f87f5f258bf872d094647791db2f4c8e", - "reference": "4360e982f87f5f258bf872d094647791db2f4c8e", + "url": "https://api.github.com/repos/guzzle/promises/zipball/9ad1e4fc607446a055b95870c7f668e93b5cff29", + "reference": "9ad1e4fc607446a055b95870c7f668e93b5cff29", "shasum": "" }, "require": { @@ -6790,7 +6790,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.5.0" + "source": "https://github.com/guzzle/promises/tree/2.5.1" }, "funding": [ { @@ -6806,20 +6806,20 @@ "type": "tidelift" } ], - "time": "2026-06-02T12:23:43+00:00" + "time": "2026-07-08T15:48:39+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.12.3", + "version": "2.13.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "7ec62dc3f44aa218487dbed81a9bf9bc647be55d" + "reference": "dad89620b7a6edb60c15858442eb2e408b45d8f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/7ec62dc3f44aa218487dbed81a9bf9bc647be55d", - "reference": "7ec62dc3f44aa218487dbed81a9bf9bc647be55d", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/dad89620b7a6edb60c15858442eb2e408b45d8f4", + "reference": "dad89620b7a6edb60c15858442eb2e408b45d8f4", "shasum": "" }, "require": { @@ -6909,7 +6909,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.12.3" + "source": "https://github.com/guzzle/psr7/tree/2.13.0" }, "funding": [ { @@ -6925,7 +6925,7 @@ "type": "tidelift" } ], - "time": "2026-06-23T15:21:08+00:00" + "time": "2026-07-16T22:23:49+00:00" }, { "name": "laravel/prompts", @@ -7745,16 +7745,16 @@ }, { "name": "mck89/peast", - "version": "v1.17.6", + "version": "v1.17.7", "source": { "type": "git", "url": "https://github.com/mck89/peast.git", - "reference": "b8b4184b1e6912669f9af155caef9050509d9f18" + "reference": "89ee39f81e82cb7ed36cc5abaf2edd43cef71770" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mck89/peast/zipball/b8b4184b1e6912669f9af155caef9050509d9f18", - "reference": "b8b4184b1e6912669f9af155caef9050509d9f18", + "url": "https://api.github.com/repos/mck89/peast/zipball/89ee39f81e82cb7ed36cc5abaf2edd43cef71770", + "reference": "89ee39f81e82cb7ed36cc5abaf2edd43cef71770", "shasum": "" }, "require": { @@ -7767,7 +7767,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.17.6-dev" + "dev-master": "1.17.7-dev" } }, "autoload": { @@ -7788,9 +7788,9 @@ "description": "Peast is PHP library that generates AST for JavaScript code", "support": { "issues": "https://github.com/mck89/peast/issues", - "source": "https://github.com/mck89/peast/tree/v1.17.6" + "source": "https://github.com/mck89/peast/tree/v1.17.7" }, - "time": "2026-04-24T08:04:05+00:00" + "time": "2026-07-21T11:56:06+00:00" }, { "name": "mglaman/phpstan-drupal", @@ -18088,5 +18088,5 @@ "prefer-lowest": false, "platform": {}, "platform-dev": {}, - "plugin-api-version": "2.9.0" + "plugin-api-version": "2.6.0" } diff --git a/composer.log b/composer.log index bbc9ad6c..78c127a1 100644 --- a/composer.log +++ b/composer.log @@ -146,3 +146,6 @@ adc4e0d2f9a48ebb29e9e4f44b1157e2|arpage|features/DIGITAL-788-drupal-core-update| df82b8830d6ba37406e5253b08d0f980|arpage|features/DIGITAL-788-drupal-core-update|Mon Jun 22 11:36:43 EDT 2026|./composer.sh require drupal/core-composer-scaffold:10.6.11 --update-with-all-dependencies --ignore-platform-reqs 837b12446d4a84fe38db17529463fb9c|arpage|features/DIGITAL-788-drupal-core-update|Mon Jun 22 11:37:38 EDT 2026|./composer.sh require drupal/core-project-message:10.6.11 --update-with-all-dependencies --ignore-platform-reqs 9f222b3a0ea442ac9e5801bdb8576d1c|Jacob Yeager|feature/DIGITAL-792-drupal-update-to-10.6.12|Mon Jul 6 15:16:14 EDT 2026|./composer.sh require drupal/core-recommended:10.6.12 drupal/core-composer-scaffold:10.6.12 drupal/core-project-message:10.6.12 --update-with-all-dependencies +32b6224154b767304fa46f2cd2666b0f|arpage|feature/DIGITAL-808-core-security-updates|Tue Jul 28 06:15:40 EDT 2026|./composer.sh require drupal/core-recommended:10.6.14 --with-all-dependencies --ignore-platform-reqs +873537afcfa938db74a386e1ec06198a|arpage|feature/DIGITAL-808-core-security-updates|Tue Jul 28 06:15:53 EDT 2026|./composer.sh require drupal/core-composer-scaffold:10.6.14 --with-all-dependencies --ignore-platform-reqs +cf5dc8061ee27663fc8968237f723ec2|arpage|feature/DIGITAL-808-core-security-updates|Tue Jul 28 06:16:49 EDT 2026|./composer.sh require drupal/core-project-message:^10.6.14 --with-all-dependencies --ignore-platform-reqs diff --git a/scripts/cloud-gov-s3-creds.sh b/scripts/cloud-gov-s3-creds.sh index a5e7a1dc..28afbf51 100755 --- a/scripts/cloud-gov-s3-creds.sh +++ b/scripts/cloud-gov-s3-creds.sh @@ -3,12 +3,19 @@ ## Get current username with no special characters. user=$(whoami | tr -dc '[:alnum:]\n\r' | tr '[:upper:]' '[:lower:]') -if [ -z "${bucket_name}" ]; then - echo -e "Error: No bucket name is set!\n" - echo -e "Export the bucket name, found with 'cf services | grep s3', then run the script again." - echo -e "This is the name of the bucket in cloud.gov, not the AWS bucket name.\n" - echo -e "Example usage:\n\texport bucket_name=project-bucket-name-environment\n\t$0\n" - return +## Find the CF s3 service name. Look on the command line, then in the environment. +cf_service=$1 +if [ -z "${cf_service}" ]; then + cf_service="${cf_s3_service}" + if [ -z "${cf_service}" ]; then + echo -e "Error: No CF s3 service name is set!\n" + echo -e "Export the CF s3 service name, found with 'cf services | grep s3', then run the script again." + echo -e "This is the name of the bucket in cloud.gov, not the AWS CF s3 service name.\n" + echo -e "Example usage:\n\texport cf_service=project-bucket-name-environment\n\t$0\n" + return + fi +else + shift fi if [ -n "$(cf orgs | grep FAILED)" ]; then @@ -17,18 +24,18 @@ fi echo "Deleting old credentials..." { - service_key="${bucket_name}-${user}-key" + service_key="${cf_service}-${user}-key" ## Delete any old keys. - cf delete-service-key "${bucket_name}" "${service_key}" -f + cf delete-service-key "${cf_service}" "${service_key}" -f } >/dev/null 2>&1 [ "${1}" = "-d" ] && echo "AWS bucket key deleted." && return echo "Creating key..." { - cf create-service-key "${bucket_name}" "${service_key}" - s3_credentials=$(cf service-key "${bucket_name}" "${service_key}" | tail -n +2) + cf create-service-key "${cf_service}" "${service_key}" + s3_credentials=$(cf service-key "${cf_service}" "${service_key}" | tail -n +2) aws_access_key=$(echo "${s3_credentials}" | jq -r '.credentials.access_key_id') aws_bucket_name=$(echo "${s3_credentials}" | jq -r '.credentials.bucket') aws_bucket_region=$(echo "${s3_credentials}" | jq -r '.credentials.region') diff --git a/scripts/delete-workflow-run-logs.sh b/scripts/delete-workflow-run-logs.sh new file mode 100755 index 00000000..414fce29 --- /dev/null +++ b/scripts/delete-workflow-run-logs.sh @@ -0,0 +1,122 @@ +#!/bin/bash + +# Bulk-delete the log archives for a GitHub Actions workflow's runs, filtered by branch. +# +# Deletes ONLY the log archive for each matching run +# (DELETE /repos/{owner}/{repo}/actions/runs/{id}/logs); the run row itself (status, +# timing, commit) remains visible in the Actions UI. +# +# Requires the `gh` CLI (authenticated) and `jq`. + +set -uo pipefail + +help(){ + echo "Usage: $0 -w -b [options]" >&2 + echo + echo " -w Workflow file name or numeric id (e.g. build-and-deploy.yml) [required]" + echo " -b Branch name or glob pattern (e.g. develop or '*-deploydev') [required]" + echo " -r Repository in owner/repo form (default: GSA/digital-gov-drupal)" + echo " -n Dry run: print the gh commands that would run; make NO changes" + echo " -h Show this help" +} + +RED='\033[0;31m' +NC='\033[0m' + +REPO="GSA/digital-gov-drupal" +DRYRUN="" + +while getopts 'w:b:r:nh' flag; do + case ${flag} in + w) WORKFLOW=${OPTARG} ;; + b) BRANCH=${OPTARG} ;; + r) REPO=${OPTARG} ;; + n) DRYRUN=1 ;; + h) help && exit 0 ;; + *) help && exit 1 ;; + esac +done + +# --- Preflight ------------------------------------------------------------- + +if ! hash gh 2>/dev/null ; then + echo "Please install the GitHub CLI: + https://github.com/cli/cli#installation" + exit 1 +fi + +if ! hash jq 2>/dev/null ; then + echo "Please install jq: + https://jqlang.github.io/jq/download/" + exit 1 +fi + +[[ -z "${WORKFLOW:-}" ]] && help && echo -e "\n${RED}Error: Missing -w flag.${NC}" && exit 1 +[[ -z "${BRANCH:-}" ]] && help && echo -e "\n${RED}Error: Missing -b flag.${NC}" && exit 1 + +if ! gh auth status >/dev/null 2>&1 ; then + echo -e "${RED}Error: gh is not authenticated.${NC} Run: gh auth login -h github.com" >&2 + exit 1 +fi + +# --- Collect matching run ids --------------------------------------------- + +run_ids=() + +if [[ "${BRANCH}" == *[\*\?\[]* ]]; then + # Glob pattern: the API branch= filter is exact-match only, so list every run for + # the workflow and match head_branch client-side with a bash glob. + echo "Listing runs for workflow '${WORKFLOW}' in ${REPO}, matching branch pattern '${BRANCH}'..." + while IFS=$'\t' read -r id head_branch; do + [[ -z "${id}" ]] && continue + if [[ "${head_branch}" == ${BRANCH} ]]; then + run_ids+=("${id}") + fi + done < <(gh api --paginate \ + "repos/${REPO}/actions/workflows/${WORKFLOW}/runs?per_page=100" \ + --jq '.workflow_runs[] | [.id, .head_branch] | @tsv') +else + # Exact branch name: let the API filter server-side. + echo "Listing runs for workflow '${WORKFLOW}' in ${REPO}, branch '${BRANCH}'..." + while read -r id; do + [[ -z "${id}" ]] && continue + run_ids+=("${id}") + done < <(gh api --paginate \ + "repos/${REPO}/actions/workflows/${WORKFLOW}/runs?branch=${BRANCH}&per_page=100" \ + --jq '.workflow_runs[].id') +fi + +matched=${#run_ids[@]} +echo "Matched ${matched} run(s)." + +if [[ "${matched}" -eq 0 ]]; then + exit 0 +fi + +# --- Delete log archives --------------------------------------------------- + +deleted=0 +failed=0 + +for id in "${run_ids[@]}"; do + cmd="gh api -X DELETE repos/${REPO}/actions/runs/${id}/logs" + if [[ -n "${DRYRUN}" ]]; then + echo "# ${cmd}" + deleted=$((deleted + 1)) + continue + fi + if ${cmd} >/dev/null 2>&1 ; then + echo "Deleted logs for run ${id}." + deleted=$((deleted + 1)) + else + echo -e "${RED}Failed to delete logs for run ${id} (already expired or no logs).${NC}" >&2 + failed=$((failed + 1)) + fi +done + +echo +if [[ -n "${DRYRUN}" ]]; then + echo "Dry run: ${matched} run(s) matched, ${deleted} deletion command(s) would run, 0 executed." +else + echo "Done: ${matched} matched, ${deleted} log archive(s) deleted, ${failed} failure(s)." +fi diff --git a/scripts/download_backup.sh b/scripts/download_backup.sh index e37b7132..74ac1789 100755 --- a/scripts/download_backup.sh +++ b/scripts/download_backup.sh @@ -58,8 +58,7 @@ fi help(){ echo "Usage: $0 [options]" >&2 echo - echo " -b The name of the S3 bucket with the backup." - echo " -e Environment of backup to download." + echo " -c The name of the CF service containing the S3 bucket with the backup." echo " -s Name of the space the backup bucket is in." echo " -d Date to retrieve backup from. Acceptable values are 'latest' or in 'YYYY-MM-DD' format and no @@ -69,45 +68,34 @@ help(){ RED='\033[0;31m' NC='\033[0m' -while getopts 'b:e:s:d:' flag; do +while getopts 'c:e:s:d:' flag; do case ${flag} in - b) backup_bucket=${OPTARG} ;; - e) env=${OPTARG} ;; + c) cf_s3_service=${OPTARG} ;; s) space=${OPTARG} ;; d) retrieve_date=${OPTARG} ;; *) help && exit 1 ;; esac done -[[ -z "${backup_bucket}" ]] && help && echo -e "\n${RED}Error: Missing -b flag.${NC}" && exit 1 -[[ -z "${env}" ]] && help && echo -e "\n${RED}Error: Missing -e flag.${NC}" && exit 1 +[[ -z "${cf_s3_service}" ]] && help && echo -e "\n${RED}Error: Missing -b flag.${NC}" && exit 1 [[ -z "${space}" ]] && help && echo -e "\n${RED}Error: Missing -s flag.${NC}" && exit 1 [[ -z "${retrieve_date}" ]] && help && echo -e "\n${RED}Error: Missing -d flag.${NC}" && exit 1 -echo "Getting backup bucket credentials..." +echo "Getting backup bucket credentials for $cf_s3_service in $space ..." { cf target -s "${space}" + script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + . "${script_dir}/cloud-gov-s3-creds.sh" ${cf_s3_service} + export bucket="${AWS_BUCKET}" +} &>/dev/null +[ $? -ne 0 ] && echo -e "\n${RED}Error: Failed to get backup bucket credentials.${NC}" && exit 1 - export service="${backup_bucket}" - export service_key="${service}-key" - cf delete-service-key "${service}" "${service_key}" -f - cf create-service-key "${service}" "${service_key}" - sleep 2 - export s3_credentials=$(cf service-key "${service}" "${service_key}" | tail -n +2) - - export AWS_ACCESS_KEY_ID=$(echo "${s3_credentials}" | jq -r '.credentials.access_key_id') - export bucket=$(echo "${s3_credentials}" | jq -r '.credentials.bucket') - export AWS_DEFAULT_REGION=$(echo "${s3_credentials}" | jq -r '.credentials.region') - export AWS_SECRET_ACCESS_KEY=$(echo "${s3_credentials}" | jq -r '.credentials.secret_access_key') - -} >/dev/null 2>&1 - -echo "Downloading backup..." +echo "Downloading backup from $bucket..." { - - aws s3 cp s3://${bucket}/${env}/${retrieve_date}.tar.gz . --no-verify-ssl 2>/dev/null - cf delete-service-key "${service}" "${service_key}" -f - -} >/dev/null 2>&1 + aws s3 cp s3://${bucket}/${retrieve_date}.sql.gz . --no-verify-ssl + script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + . "${script_dir}/cloud-gov-s3-creds.sh" -d +} &>/dev/null +[ $? -ne 0 ] && echo -e "\n${RED}Error: Failed to download backup from S3 bucket.${NC}" && exit 1 echo "File saved: ${retrieve_date}.tar.gz" diff --git a/scripts/pipeline/cloud-gov-waf-version.sh b/scripts/pipeline/cloud-gov-waf-version.sh index fbb8c2c4..bf7d9c86 100755 --- a/scripts/pipeline/cloud-gov-waf-version.sh +++ b/scripts/pipeline/cloud-gov-waf-version.sh @@ -11,7 +11,7 @@ # include updating it in our regular review process. # NB: Mainline nginx versions are denoted by an even number in the second part of the version number. -NGINX_VERSION=1.28.3 +NGINX_VERSION=1.30.3 export nginx_version=${NGINX_VERSION} diff --git a/terraform/applications/nginx-waf/.docker/Dockerfile b/terraform/applications/nginx-waf/.docker/Dockerfile index 128cc251..4b89968a 100644 --- a/terraform/applications/nginx-waf/.docker/Dockerfile +++ b/terraform/applications/nginx-waf/.docker/Dockerfile @@ -1,5 +1,5 @@ ARG modsecurity_nginx_version="1.0.3" -ARG nginx_version="1.28.3" +ARG nginx_version="1.30.3" ARG ubuntu_version="jammy" FROM docker.io/ubuntu:${ubuntu_version} diff --git a/terraform/applications/nginx-waf/.docker/RUNBOOK.md b/terraform/applications/nginx-waf/.docker/RUNBOOK.md index 81129f64..21b9dca0 100644 --- a/terraform/applications/nginx-waf/.docker/RUNBOOK.md +++ b/terraform/applications/nginx-waf/.docker/RUNBOOK.md @@ -14,7 +14,7 @@ The `Dockerfile` initializes a Docker image that is based on the Ubuntu `jammy` 1. **ARG Values Declaration** ``` ARG modsecurity_nginx_version="1.0.3" - ARG nginx_version="1.28.3" + ARG nginx_version="1.30.3" ARG ubuntu_version="jammy" ``` These environment variables are important because they allow the builder to specify the exact versions of the components that will be built. diff --git a/terraform/applications/nginx-waf/buildpack.yml b/terraform/applications/nginx-waf/buildpack.yml index bce241dc..a40dc23b 100644 --- a/terraform/applications/nginx-waf/buildpack.yml +++ b/terraform/applications/nginx-waf/buildpack.yml @@ -1,3 +1,3 @@ --- nginx: - version: 1.28.3 + version: 1.30.3 diff --git a/web/modules/custom/default_content_config/content/config_pages/c1b5df3b-65ae-4e70-b4af-f63647b9c069.yml b/web/modules/custom/default_content_config/content/config_pages/c1b5df3b-65ae-4e70-b4af-f63647b9c069.yml index 4a6be990..858c8c19 100644 --- a/web/modules/custom/default_content_config/content/config_pages/c1b5df3b-65ae-4e70-b4af-f63647b9c069.yml +++ b/web/modules/custom/default_content_config/content/config_pages/c1b5df3b-65ae-4e70-b4af-f63647b9c069.yml @@ -40,7 +40,7 @@ default: title: 'Office of the Inspector General' options: { } - - uri: 'https://www.gsa.gov/reference/reports/budget-performance' + uri: 'https://www.gsa.gov/about-us/newsroom/budget-and-performance' title: 'Performance reports' options: { } - diff --git a/web/modules/custom/site_wrapper/site_wrapper.install b/web/modules/custom/site_wrapper/site_wrapper.install new file mode 100644 index 00000000..f1bda6ca --- /dev/null +++ b/web/modules/custom/site_wrapper/site_wrapper.install @@ -0,0 +1,40 @@ +getStorage('config_pages'); + $ids = \Drupal::entityQuery('config_pages') + ->accessCheck(FALSE) + ->condition('type', 'identifier') + ->execute(); + + $updated = 0; + foreach ($storage->loadMultiple($ids) as $config_page) { + $links = $config_page->get('field_links')->getValue(); + $changed = FALSE; + foreach ($links as $delta => $link) { + // Only rewrite the known stale URI, so a link that has already been + // corrected by hand is left alone. + if (($link['uri'] ?? '') === $old_uri) { + $links[$delta]['uri'] = $new_uri; + $changed = TRUE; + } + } + if ($changed) { + $config_page->set('field_links', $links)->save(); + $updated++; + } + } + + return t('Updated the "Performance reports" link on @count identifier config page(s).', ['@count' => $updated]); +} diff --git a/web/themes/custom/digital_gov/css/new/_article.scss b/web/themes/custom/digital_gov/css/new/_article.scss index 6d4b3dc5..13072657 100644 --- a/web/themes/custom/digital_gov/css/new/_article.scss +++ b/web/themes/custom/digital_gov/css/new/_article.scss @@ -57,22 +57,6 @@ article > header { article { @include u-margin-bottom(5); - header { - .authors-list--inline { - display: flex; - - @include at-media("tablet-lg") { - display: none; - } - } - - .meta { - @include at-media("tablet-lg") { - @include u-display("none"); - } - } - } - .meta { @include u-margin-top("205"); @include u-display("flex"); diff --git a/web/themes/custom/digital_gov/css/new/_authors-list.scss b/web/themes/custom/digital_gov/css/new/_authors-list.scss index 52574b1f..0069ff55 100644 --- a/web/themes/custom/digital_gov/css/new/_authors-list.scss +++ b/web/themes/custom/digital_gov/css/new/_authors-list.scss @@ -1,5 +1,4 @@ // Styles for the list of authors generally found on blog posts and event pages -// NOTE: The authors-list is included twice on the page. Once for desktop, the other for mobile. @use "uswds-core" as *; // authors landing override @@ -55,7 +54,7 @@ align-items: center; border: none; display: flex; - margin-bottom: units("05"); + margin-bottom: units("205"); margin-left: 0; margin-right: units("105"); margin-top: units("05"); @@ -73,7 +72,14 @@ .author__photo-img { border: 1px color("indigo-30") solid; - margin-right: units("05"); + margin-right: units(1); @include u-circle(3); } } + +// Single-author byline showing the author's agency (blog post header) +.authors-list--inline.authors-list--with-agency { + .author__photo-img { + @include u-circle(5); + } +} diff --git a/web/themes/custom/digital_gov/css/new/_uswds-theme.scss b/web/themes/custom/digital_gov/css/new/_uswds-theme.scss index 9bf4135a..bd0032ff 100644 --- a/web/themes/custom/digital_gov/css/new/_uswds-theme.scss +++ b/web/themes/custom/digital_gov/css/new/_uswds-theme.scss @@ -36,7 +36,7 @@ i.e. $theme-type-scale-lg: 8, $theme-type-scale-xl: 11, $theme-font-weight-thin: 100, - $theme-font-weight-light: 200, + $theme-font-weight-light: 300, $theme-font-weight-medium: 600, $theme-font-weight-semibold: 700, $theme-font-weight-bold: 800, diff --git a/web/themes/custom/digital_gov/package-lock.json b/web/themes/custom/digital_gov/package-lock.json index fbaba723..cb5039ca 100644 --- a/web/themes/custom/digital_gov/package-lock.json +++ b/web/themes/custom/digital_gov/package-lock.json @@ -29,7 +29,7 @@ "postcss-csso": "^6.0.1", "sass": "^1.69.7", "sass-embedded": "^1.69.7", - "sharp": "^0.33.3", + "sharp": "^0.35.2", "terser-webpack-plugin": "^5.4.0", "webpack-stream": "^7.0.0" }, @@ -50,7 +50,7 @@ "husky": "^8.0.3", "image-size": "^1.1.1", "markdownlint-cli": "^0.49.0", - "postcss": "^8.5.14", + "postcss": "^8.5.23", "prettier": "^2.8.8", "prettier-plugin-go-template": "^0.0.13", "stylelint": "^15.11.0", @@ -1122,9 +1122,10 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.2.0.tgz", - "integrity": "sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", + "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" @@ -1327,432 +1328,549 @@ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "deprecated": "Use @eslint/object-schema instead" }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.4.tgz", - "integrity": "sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.2.tgz", + "integrity": "sha512-eEieHsMksAW4IiO5NzauESRl2D2qz3J/kwUxUrSfV06A93eEaRfMpHXyUb1mAqrR7i8U9A0GRqE9pjn6u1Jjpg==", "cpu": [ "arm64" ], + "license": "Apache-2.0", "optional": true, "os": [ "darwin" ], "engines": { - "glibc": ">=2.26", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.0.2" + "@img/sharp-libvips-darwin-arm64": "1.3.1" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.4.tgz", - "integrity": "sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.2.tgz", + "integrity": "sha512-BaktuGPCeHJMARpodR8jK4uKiZrPAy9WrfQW0sdI37clracq8Bp01AYS3SZgi5FS/y5twa9t4+LIuuxQjqRrWw==", "cpu": [ "x64" ], + "license": "Apache-2.0", "optional": true, "os": [ "darwin" ], "engines": { - "glibc": ">=2.26", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.0.2" + "@img/sharp-libvips-darwin-x64": "1.3.1" + } + }, + "node_modules/@img/sharp-freebsd-wasm32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.2.tgz", + "integrity": "sha512-YoAxdnd8hPUkvLHd3bWY+YA8nw3xM/RyRopYucNsWHVSan8NLVM3X2volsfoRDcXdUJPg6tXahSd7HXPK7lRnw==", + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "dependencies": { + "@img/sharp-wasm32": "0.35.2" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.2.tgz", - "integrity": "sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.1.tgz", + "integrity": "sha512-4V/M3roRMTYjiwZY9IOVQOE8OyeCxFAkYmyZDrZl51uOKjibm3oeEJ4WAmLxutAfzFbC9jqUiPs2gbnGflH+7g==", "cpu": [ "arm64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "darwin" ], - "engines": { - "macos": ">=11", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.2.tgz", - "integrity": "sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.1.tgz", + "integrity": "sha512-c0/DxItpJv2+dGhgycJBBgotdqruGYDvA79drdh0MD1dFpy7JzJ/PlXwi1H4rFf0eTy8tgbI91aHDnZIceY3jQ==", "cpu": [ "x64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "darwin" ], - "engines": { - "macos": ">=10.13", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.2.tgz", - "integrity": "sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.1.tgz", + "integrity": "sha512-aGGy9aWzXgHBG7HNyQPWorZthlp7+x6fDRoPAQbGO3ThcttuTyKIx3NuSHb6zb4gBNq6/yNn9f1cy9nFKS/Vmg==", "cpu": [ "arm" ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" ], - "engines": { - "glibc": ">=2.28", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.2.tgz", - "integrity": "sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.1.tgz", + "integrity": "sha512-JznefmcK9j1JKPz8AkQDh89kjojubyfOasWBPKfzMIhPwsgDy9evpE/naJTXXXmghS1iFwR8u/kTwh/I2/+GCw==", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.1.tgz", + "integrity": "sha512-1EkwGNCZk6iWNCMWqrvdJ+r1j0PT1zIz60CNPhYnJlK/zyeWqlsPZIe+ocBVqPF8k/Ssee/NCk+tE9Ryrko6ng==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.1.tgz", + "integrity": "sha512-Ilays+w2bXdnxzxtQdmXR62u8o8GYa3eL4+Gr+1KiE4xperMZUslRaVPJwwPkzlHEjGfXAfRVAa/7CYCtSqsBw==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" ], - "engines": { - "glibc": ">=2.26", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.2.tgz", - "integrity": "sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.1.tgz", + "integrity": "sha512-VfBwVHQTbRoj4XlpA/KLZ7ltgMpz+4WSejFzQ+GnoImjo1PtEJ59QB2qR1xQEeRPYIkNrPIm2L4cICMvz4C2ew==", "cpu": [ "s390x" ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" ], - "engines": { - "glibc": ">=2.28", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.2.tgz", - "integrity": "sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.1.tgz", + "integrity": "sha512-+c8ukgwU62DS54nCAjw7keOfHUkmr0B5QHEdcOqRnodF/MNXJbVI8Eopoj4B/0H8Asr65I+A4Amrn7a85/md6A==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" ], - "engines": { - "glibc": ">=2.26", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.2.tgz", - "integrity": "sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.1.tgz", + "integrity": "sha512-qlKb/pwbkAi1WMsJrYHk7CuDrd12s27U2QnRhFYUoJNrRCmkosMTttuRFat/DDB3IlDm5qE1TJgZ4JDnHX8Ldw==", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" ], - "engines": { - "musl": ">=1.2.2", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.2.tgz", - "integrity": "sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.1.tgz", + "integrity": "sha512-yO21HwoUVLN8Qa+/SBjQLMYwBWAVJjeGPNe+hc0OUeMeifEtJqu5a1c4HayE1nNpDih9y3/KkoltfkDodmKAlg==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" ], - "engines": { - "musl": ">=1.2.2", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.4.tgz", - "integrity": "sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.2.tgz", + "integrity": "sha512-SE4kzF2mepn6z+6E7L6lsV8FzuLL6IPQdyX8ZiwROAG/G8td+hP/m7FsFPwidtrF19gvajuC9l6TxAVcsA4S7A==", "cpu": [ "arm" ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "glibc": ">=2.28", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.0.2" + "@img/sharp-libvips-linux-arm": "1.3.1" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.4.tgz", - "integrity": "sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.2.tgz", + "integrity": "sha512-af12Pnd0ZGu2HfP8NayB0kk6eC/lrfbQE6HlR4jD+34wdJ1Vw9TF6TMn6ZvffT+WgqVsl0hRbmNvz2u/23VmwA==", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.3.1" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.2.tgz", + "integrity": "sha512-hYSBm7zcNtDCozCxQHYZJiu63b/bXsgRZuOxCIBZsStMM9Vap47iFHdbX4kCvQsblPB/k+clhELpdQJHQLSHvg==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "glibc": ">=2.26", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.0.2" + "@img/sharp-libvips-linux-ppc64": "1.3.1" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.2.tgz", + "integrity": "sha512-qQt0Kc13+Hoan/Awq/qMSQw3L+RI1NCRPgD5cUJ/1WSSmIoysLOc72jlRM3E0OHN9Yr313jgeQ2T+zW+F03QFA==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.3.1" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.4.tgz", - "integrity": "sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.2.tgz", + "integrity": "sha512-E4fLLfRPzDLlEeDaTzI98OFLcv++WL5ChLLMwPoVd0CIoZQqupBSNbOisPL5am9XsbQ9T84+iiMpUvbFtkunbA==", "cpu": [ "s390x" ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "glibc": ">=2.31", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.0.2" + "@img/sharp-libvips-linux-s390x": "1.3.1" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.4.tgz", - "integrity": "sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.2.tgz", + "integrity": "sha512-gi0zFJJRLswfCZmHtJdikXPOc5u7qamSOS3NHedLqLd4W8Q0NqjdBr6TTRIgsfFjqfTsHFgdfvJ9LwqSgcHiAA==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "glibc": ">=2.26", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.0.2" + "@img/sharp-libvips-linux-x64": "1.3.1" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.4.tgz", - "integrity": "sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.2.tgz", + "integrity": "sha512-siWbOW1u6HFnFLrp0waKyW7VEf7jYvcDWdrXEFa8AkdAQgEvuu5Fz8/Y70w9EeqAdwDtfU012BhEHHaDqvQNzg==", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "musl": ">=1.2.2", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.0.2" + "@img/sharp-libvips-linuxmusl-arm64": "1.3.1" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.4.tgz", - "integrity": "sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.2.tgz", + "integrity": "sha512-YBqMMcjDi4QGYiSn4vNOYBhmlC4z5AXqkOUUqI2e0AFA4urNv4ESgOgwNl3K+4etQhha0twXlzeF20bbULm9Yg==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "musl": ">=1.2.2", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.0.2" + "@img/sharp-libvips-linuxmusl-x64": "1.3.1" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.4.tgz", - "integrity": "sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.2.tgz", + "integrity": "sha512-Mrv4JQNYVQ94xH+jzZ9r+gowleN8mv2FTgKT+PI6bx5C0G8TdNYndu161pg2i7uoBwxy2ImPMHrJOM2LZef7Bw==", + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.1" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-webcontainers-wasm32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.2.tgz", + "integrity": "sha512-QNV27pxs9wpApEiCfvHM1RDoP1w1+2KrUWWDPEhEwg+latvOrfuhWrHWZKwdSFwU6jh3myjw/yOCRsUIuOft3g==", "cpu": [ "wasm32" ], + "license": "Apache-2.0", "optional": true, "dependencies": { - "@emnapi/runtime": "^1.1.1" + "@img/sharp-wasm32": "0.35.2" }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.2.tgz", + "integrity": "sha512-BiVRYc/t6/Vl3e1hBx0hugG4oN9Pydf4fgMSpxTQJmwGUg/YoXTWHiFeRymHfCZzifxu4F4rpk/I67D0LQ20wQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.4.tgz", - "integrity": "sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.2.tgz", + "integrity": "sha512-YYEhx9PImCC7T0tI8JDMi4DB9LwLCXCU5OWNYEXAxh5Q1ShKkyC6byxzoBJ3gEFDnH2lQckWuDe70G7mB2XJog==", "cpu": [ "ia32" ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" + "node": "^20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.4.tgz", - "integrity": "sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.2.tgz", + "integrity": "sha512-imoOyBcoM/iiUr4J6VPpCNjPnjvP/Gks95898yB8YqoGGYmHYbOyCuNv9FMhFgtaiHFGbHW8bxKqRV6VjtXThQ==", "cpu": [ "x64" ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" @@ -3086,9 +3204,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "dev": true, "license": "MIT", "dependencies": { @@ -4028,9 +4146,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -4347,6 +4465,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dev": true, "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" @@ -4940,9 +5059,10 @@ } }, "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", "engines": { "node": ">=8" } @@ -5905,9 +6025,9 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", + "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", "funding": [ { "type": "github", @@ -7155,9 +7275,9 @@ } }, "node_modules/immutable": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.8.tgz", - "integrity": "sha512-d/Ld9aLbKpNwyl0KiM2CT1WYvkitQ1TSvmRtkcV8FKStiDoA7Slzgjmb/1G2yhKM1p0XeNOieaTbFZmU1d3Xuw==", + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.9.tgz", + "integrity": "sha512-ObHy4YN7ycwZOUCLI1/6svfyAFu7vL8RhAvVu/bh/RZW9EPlOyDaQ9jDQWCtdqzaXUjgXZCW1migtHE7YI7UGQ==", "license": "MIT" }, "node_modules/import-fresh": { @@ -7973,9 +8093,9 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/linkify-it": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.1.tgz", - "integrity": "sha512-wVoTjP4Q6R0NW5hiZkVJaFZPWgtXfoGF+6LucL3/FtiNjmcHhYjEr5f1Kqjirc1nBW07J/ZuRFumqr2oqccEWg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz", + "integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==", "dev": true, "funding": [ { @@ -8227,16 +8347,16 @@ } }, "node_modules/markdownlint-cli/node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/markdownlint-cli/node_modules/ignore": { @@ -9124,9 +9244,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "funding": [ { "type": "github", @@ -9689,9 +9809,9 @@ } }, "node_modules/postcss": { - "version": "8.5.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", - "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", "funding": [ { "type": "opencollective", @@ -9708,7 +9828,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.11", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -11101,48 +11221,54 @@ } }, "node_modules/sharp": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.4.tgz", - "integrity": "sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==", - "hasInstallScript": true, + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.2.tgz", + "integrity": "sha512-FVtFjtBCMiJS6yb5CX7Sop45WFMpeGw6oRKuJnXYgf/f1ms/D7LE/ZUSNxnW7rZ/dbslQWYkoqFHGPaDBtaK4w==", + "license": "Apache-2.0", "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.3", - "semver": "^7.6.0" + "@img/colour": "^1.1.0", + "detect-libc": "^2.1.2", + "semver": "^7.8.4" }, "engines": { - "libvips": ">=8.15.2", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.33.4", - "@img/sharp-darwin-x64": "0.33.4", - "@img/sharp-libvips-darwin-arm64": "1.0.2", - "@img/sharp-libvips-darwin-x64": "1.0.2", - "@img/sharp-libvips-linux-arm": "1.0.2", - "@img/sharp-libvips-linux-arm64": "1.0.2", - "@img/sharp-libvips-linux-s390x": "1.0.2", - "@img/sharp-libvips-linux-x64": "1.0.2", - "@img/sharp-libvips-linuxmusl-arm64": "1.0.2", - "@img/sharp-libvips-linuxmusl-x64": "1.0.2", - "@img/sharp-linux-arm": "0.33.4", - "@img/sharp-linux-arm64": "0.33.4", - "@img/sharp-linux-s390x": "0.33.4", - "@img/sharp-linux-x64": "0.33.4", - "@img/sharp-linuxmusl-arm64": "0.33.4", - "@img/sharp-linuxmusl-x64": "0.33.4", - "@img/sharp-wasm32": "0.33.4", - "@img/sharp-win32-ia32": "0.33.4", - "@img/sharp-win32-x64": "0.33.4" + "@img/sharp-darwin-arm64": "0.35.2", + "@img/sharp-darwin-x64": "0.35.2", + "@img/sharp-freebsd-wasm32": "0.35.2", + "@img/sharp-libvips-darwin-arm64": "1.3.1", + "@img/sharp-libvips-darwin-x64": "1.3.1", + "@img/sharp-libvips-linux-arm": "1.3.1", + "@img/sharp-libvips-linux-arm64": "1.3.1", + "@img/sharp-libvips-linux-ppc64": "1.3.1", + "@img/sharp-libvips-linux-riscv64": "1.3.1", + "@img/sharp-libvips-linux-s390x": "1.3.1", + "@img/sharp-libvips-linux-x64": "1.3.1", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.1", + "@img/sharp-libvips-linuxmusl-x64": "1.3.1", + "@img/sharp-linux-arm": "0.35.2", + "@img/sharp-linux-arm64": "0.35.2", + "@img/sharp-linux-ppc64": "0.35.2", + "@img/sharp-linux-riscv64": "0.35.2", + "@img/sharp-linux-s390x": "0.35.2", + "@img/sharp-linux-x64": "0.35.2", + "@img/sharp-linuxmusl-arm64": "0.35.2", + "@img/sharp-linuxmusl-x64": "0.35.2", + "@img/sharp-webcontainers-wasm32": "0.35.2", + "@img/sharp-win32-arm64": "0.35.2", + "@img/sharp-win32-ia32": "0.35.2", + "@img/sharp-win32-x64": "0.35.2" } }, "node_modules/sharp/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -11151,9 +11277,9 @@ } }, "node_modules/shell-quote": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.4.tgz", - "integrity": "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.10.0.tgz", + "integrity": "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -12035,9 +12161,9 @@ "dev": true }, "node_modules/svgo": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.2.tgz", - "integrity": "sha512-TyzE4NVGLUFy+H/Uy4N6c3G0HEeprsVfge6Lmq+0FdQQ/zqoVYB62IsBZORsiL+o96s6ff/V6/3UQo/C0cgCAA==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.3.tgz", + "integrity": "sha512-5EZD0pafXX6PphdwOGCiVLDSaV1xyuQao2blHajHLsPxr07q4mmEjdtXEWgG07ae2mIz8Ex2CDXNCTiXhy3Khw==", "license": "MIT", "dependencies": { "commander": "^7.2.0", diff --git a/web/themes/custom/digital_gov/package.json b/web/themes/custom/digital_gov/package.json index dada94da..4e9b74be 100644 --- a/web/themes/custom/digital_gov/package.json +++ b/web/themes/custom/digital_gov/package.json @@ -53,7 +53,7 @@ "postcss-csso": "^6.0.1", "sass": "^1.69.7", "sass-embedded": "^1.69.7", - "sharp": "^0.33.3", + "sharp": "^0.35.2", "terser-webpack-plugin": "^5.4.0", "webpack-stream": "^7.0.0" }, @@ -74,7 +74,7 @@ "husky": "^8.0.3", "image-size": "^1.1.1", "markdownlint-cli": "^0.49.0", - "postcss": "^8.5.14", + "postcss": "^8.5.23", "prettier": "^2.8.8", "prettier-plugin-go-template": "^0.0.13", "stylelint": "^15.11.0", diff --git a/web/themes/custom/digital_gov/templates/node/node--news.html.twig b/web/themes/custom/digital_gov/templates/node/node--news.html.twig index 6081d7ed..70a59a51 100644 --- a/web/themes/custom/digital_gov/templates/node/node--news.html.twig +++ b/web/themes/custom/digital_gov/templates/node/node--news.html.twig @@ -78,13 +78,14 @@ {% if content.field_authors|field_value %} {{ include('@digital_gov/partials/authors-list.html.twig', { inline: true, + show_agency: true, authors: content.field_authors|field_value, }, with_context: false) }} {% endif %}
{{ created }}Published on: {{ created }}
@@ -92,7 +93,7 @@
-
+
{{ content.body|field_value }}
@@ -102,19 +103,6 @@
- {% if content.field_authors|field_value %} - {{ include('@digital_gov/partials/authors-list.html.twig', { - inline: false, - authors: content.field_authors|field_value, - }, with_context: false) }} - {% endif %} - -
-
- {{ created }} -
-
- {{ include('@digital_gov/partials/primary-communities.html.twig') }} {{ content.field_topics }} diff --git a/web/themes/custom/digital_gov/templates/partials/authors-list.html.twig b/web/themes/custom/digital_gov/templates/partials/authors-list.html.twig index 611304f7..1641ac08 100644 --- a/web/themes/custom/digital_gov/templates/partials/authors-list.html.twig +++ b/web/themes/custom/digital_gov/templates/partials/authors-list.html.twig @@ -4,11 +4,14 @@ EXPECTED VARIABLES: - inline: boolean - authors: render array of author nodes + - show_agency: boolean (optional) — when there is a single author, render + their agency name below their name (used in the blog post byline) #} -
+{% set with_agency = show_agency|default(false) and authors|length == 1 %} +
{% for author in authors %} - {% set display_mode = inline ? 'teaser_inline' : 'teaser' %} + {% set display_mode = inline and not with_agency ? 'teaser_inline' : 'teaser' %} {{ drupal_entity('node', author['#node'].id(), display_mode) }} {% endfor %}