diff --git a/.github/workflows/check-editor-releases.yml b/.github/workflows/check-editor-releases.yml index b46bca3..b79371a 100644 --- a/.github/workflows/check-editor-releases.yml +++ b/.github/workflows/check-editor-releases.yml @@ -15,6 +15,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 + with: + # The editor build installs third-party packages; keep the write + # token off disk and hand it only to the push step. + persist-credentials: false - name: Get latest exelearning release id: check @@ -28,6 +32,12 @@ jobs: echo "found=false" >> $GITHUB_OUTPUT exit 0 fi + # The tag comes from another repository and ends up in shell commands, + # file names and a git commit: accept only a plain version tag. + if ! [[ "$LATEST" =~ ^v[0-9][0-9A-Za-z.-]*$ ]]; then + echo "::error::Unexpected editor release tag format" + exit 1 + fi echo "Latest editor release: $LATEST" echo "tag=$LATEST" >> $GITHUB_OUTPUT @@ -79,21 +89,25 @@ jobs: - name: Compute version if: steps.check.outputs.found == 'true' id: version + env: + TAG: ${{ steps.check.outputs.tag }} run: | - TAG="${{ steps.check.outputs.tag }}" VERSION="${TAG#v}" echo "version=$VERSION" >> $GITHUB_OUTPUT echo "tag=$TAG" >> $GITHUB_OUTPUT - name: Create package if: steps.check.outputs.found == 'true' - run: | - make package VERSION=${{ steps.version.outputs.version }} + env: + VERSION: ${{ steps.version.outputs.version }} + run: make package VERSION="$VERSION" - name: Update editor version marker if: steps.check.outputs.found == 'true' + env: + TAG: ${{ steps.check.outputs.tag }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - TAG="${{ steps.check.outputs.tag }}" echo "$TAG" > .editor-version # Keep the playground blueprint's editor URL in sync with .editor-version, # otherwise the preview stays pinned to the hardcoded version. @@ -106,7 +120,7 @@ jobs: git config user.email "github-actions[bot]@users.noreply.github.com" git add .editor-version blueprint.json git commit -m "Update editor version to $TAG" - git push + git push "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "HEAD:${GITHUB_REF_NAME}" - name: Build Playground URL for this release if: steps.check.outputs.found == 'true' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4c533d2..43c3df8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -36,6 +36,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 + with: + # Nothing here pushes; keep the write token off disk while the + # editor build installs third-party packages. + persist-credentials: false - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -51,8 +55,16 @@ jobs: uses: oven-sh/setup-bun@v2 - name: Set environment variables + # Dispatch inputs are read through env, never expanded into the script, + # and validated before they reach GITHUB_ENV (a newline there would + # define arbitrary variables for every later step). + env: + INPUT_RELEASE: ${{ github.event.inputs.release_tag }} + INPUT_REPO_URL: ${{ github.event.inputs.editor_repo_url }} + INPUT_REF: ${{ github.event.inputs.editor_ref }} + INPUT_REF_TYPE: ${{ github.event.inputs.editor_ref_type }} run: | - if [ "${{ github.event_name }}" = "release" ]; then + if [ "$GITHUB_EVENT_NAME" = "release" ]; then RAW_TAG="${GITHUB_REF##*/}" VERSION_TAG="${RAW_TAG#v}" echo "RELEASE_TAG=${VERSION_TAG}" >> $GITHUB_ENV @@ -62,14 +74,16 @@ jobs: echo "EXELEARNING_EDITOR_REF=v${VERSION_TAG}" >> $GITHUB_ENV echo "EXELEARNING_EDITOR_REF_TYPE=tag" >> $GITHUB_ENV else - INPUT_RELEASE="${{ github.event.inputs.release_tag }}" if [ -z "$INPUT_RELEASE" ]; then INPUT_RELEASE="manual-$(date +%Y%m%d)-${GITHUB_SHA::7}" fi + [[ "$INPUT_RELEASE" =~ ^[0-9A-Za-z._-]+$ ]] || { echo "::error::Invalid release_tag"; exit 1; } + [[ "$INPUT_REPO_URL" =~ ^https://[0-9A-Za-z._/-]+$ ]] || { echo "::error::Invalid editor_repo_url"; exit 1; } + [[ "$INPUT_REF" =~ ^[0-9A-Za-z._/-]+$ ]] || { echo "::error::Invalid editor_ref"; exit 1; } echo "RELEASE_TAG=${INPUT_RELEASE}" >> $GITHUB_ENV - echo "EXELEARNING_EDITOR_REPO_URL=${{ github.event.inputs.editor_repo_url }}" >> $GITHUB_ENV - echo "EXELEARNING_EDITOR_REF=${{ github.event.inputs.editor_ref }}" >> $GITHUB_ENV - echo "EXELEARNING_EDITOR_REF_TYPE=${{ github.event.inputs.editor_ref_type }}" >> $GITHUB_ENV + echo "EXELEARNING_EDITOR_REPO_URL=${INPUT_REPO_URL}" >> $GITHUB_ENV + echo "EXELEARNING_EDITOR_REF=${INPUT_REF}" >> $GITHUB_ENV + echo "EXELEARNING_EDITOR_REF_TYPE=${INPUT_REF_TYPE}" >> $GITHUB_ENV fi - name: Build static editor diff --git a/package-lock.json b/package-lock.json index e912cc4..0c9c86f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3234,21 +3234,21 @@ } }, "node_modules/@wordpress/env": { - "version": "11.15.0", - "resolved": "https://registry.npmjs.org/@wordpress/env/-/env-11.15.0.tgz", - "integrity": "sha512-FZq3eMDXBlZVZU8jVSX/4XoexgiBM4ZBqk69Mh23pz+1MMeQ13l7g5v7zKAAnyA3F9eHd+1sWsUpQnuS1f1T6Q==", + "version": "11.16.0", + "resolved": "https://registry.npmjs.org/@wordpress/env/-/env-11.16.0.tgz", + "integrity": "sha512-B09FByMnGleYaBa4LESZ9Bp/71/EOvovjqvwhXhZjZk25fLIsed4gslZXW9c3EodD2oxF5loHUCMzCAqotGRBg==", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { "@inquirer/prompts": "^7.2.0", "@wp-playground/cli": "^3.0.48", - "adm-zip": "^0.6.0", + "adm-zip": "^0.6.1", "chalk": "^4.1.1", "copy-dir": "^1.3.0", "cross-spawn": "^7.0.6", "docker-compose": "^0.24.3", "got": "^11.8.5", - "js-yaml": "^3.15.0", + "js-yaml": "^3.15.2", "ora": "^4.0.2", "rimraf": "^5.0.10", "simple-git": "^3.32.3", @@ -3258,8 +3258,7 @@ "wp-env": "bin/wp-env" }, "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" + "node": ">=18.12.0" } }, "node_modules/@wordpress/escape-html": { @@ -4054,9 +4053,9 @@ "license": "Apache-2.0" }, "node_modules/body-parser": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", - "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "version": "1.20.8", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.8.tgz", + "integrity": "sha512-JNcyFQ64OiijEkPzUBTCe+hyPXUD/3LEldGQ6iF5LR1w00mx9o7xtDWHXBY2iItjdCFGoilOLNQbH943ut7pHA==", "dev": true, "license": "MIT", "dependencies": { @@ -4068,7 +4067,7 @@ "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", - "qs": "~6.14.0", + "qs": "~6.16.0", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" @@ -4091,6 +4090,23 @@ "node": ">=0.10.0" } }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz", + "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/bottleneck": { "version": "2.19.5", "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", @@ -4474,9 +4490,9 @@ "license": "MIT" }, "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.10.0.tgz", + "integrity": "sha512-AidJptpBJmjTclAp9BkLwJi0T93fo5epJnbaZslpg6QVzpHjAiveF55mE9AcUJiGMqRHgMDY8soMsQtuNYMHfw==", "dev": true, "license": "MIT" }, @@ -6740,9 +6756,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.16", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", - "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "version": "3.3.19", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", + "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", "dev": true, "funding": [ { @@ -7839,15 +7855,15 @@ } }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, @@ -7859,14 +7875,14 @@ } }, "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" @@ -8935,9 +8951,9 @@ } }, "node_modules/yaml": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz", + "integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==", "dev": true, "license": "ISC", "bin": {