From bbc2f369b8f2893d1fb505462f6e64e5cd94653e Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Fri, 31 Jul 2026 15:24:15 -0400 Subject: [PATCH 1/7] feat: Add .gitignore to exclude .DS_Store files --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store From 612b73a097595b7b43450e45bf5422661fcd1787 Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Fri, 31 Jul 2026 15:24:43 -0400 Subject: [PATCH 2/7] chore: Update action versions in workflows and action.yml --- .github/workflows/clean-release-notes.yml | 2 +- .github/workflows/dependency-review.yml | 4 ++-- .github/workflows/labeler.yml | 4 ++-- .github/workflows/test.yml | 10 +++++----- action.yml | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/clean-release-notes.yml b/.github/workflows/clean-release-notes.yml index ca2c3cd..12f288f 100644 --- a/.github/workflows/clean-release-notes.yml +++ b/.github/workflows/clean-release-notes.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Remove ticket prefixes from release notes - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | const release = context.payload.release; diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index df68b43..1c41cbc 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -10,8 +10,8 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout repository' - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: 'Dependency Review' - uses: actions/dependency-review-action@v4 + uses: actions/dependency-review-action@v5 with: comment-summary-in-pr: on-failure diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 4df5d85..068efc8 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -19,10 +19,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Run Labeler - uses: crazy-max/ghaction-github-labeler@de749cf181958193cb7debf1a9c5bb28922f3e1b + uses: crazy-max/ghaction-github-labeler@548a7c3603594ec17c819e1239f281a3b801ab4d # pin@v6.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} yaml-file: .github/labels.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e6852d5..ecee6b2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ jobs: name: Test the action with a setup token steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v7 - name: Install the Linode CLI uses: ./ with: @@ -19,7 +19,7 @@ jobs: name: Test the action without a setup token steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v7 - name: Install the Linode CLI uses: ./ - name: Run an authenticated command @@ -32,7 +32,7 @@ jobs: name: Test the action with an explicit version steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v7 - name: Install the Linode CLI uses: ./ with: @@ -46,7 +46,7 @@ jobs: name: Test the action with optional dependencies steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v7 - name: Install the Linode CLI uses: ./ with: @@ -62,7 +62,7 @@ jobs: name: Test the action with upgrade disabled steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v7 - name: Install the Linode CLI uses: ./ with: diff --git a/action.yml b/action.yml index 168fd54..14047a6 100644 --- a/action.yml +++ b/action.yml @@ -27,7 +27,7 @@ runs: run: echo "::add-mask::${{ inputs.token }}" - name: Setup Python 3 - uses: actions/setup-python@v5 + uses: actions/setup-python@v7 if: ${{ inputs.setup-python == 'true' }} with: python-version: '3.x' From 50a8faa4ddbd6fa0de678c1640fd70d0efebf4b6 Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Fri, 31 Jul 2026 15:45:11 -0400 Subject: [PATCH 3/7] fix: prevent shell injection from action inputs in run scripts Pass token and install args through env vars instead of expanding ${{ }} expressions directly in composite run steps. --- action.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index 14047a6..252efc5 100644 --- a/action.yml +++ b/action.yml @@ -24,7 +24,9 @@ runs: steps: - name: Mask the input token shell: bash - run: echo "::add-mask::${{ inputs.token }}" + env: + TOKEN: ${{ inputs.token }} + run: echo "::add-mask::$TOKEN" - name: Setup Python 3 uses: actions/setup-python@v7 @@ -66,13 +68,15 @@ runs: UPGRADE: ${{ inputs.upgrade }} - name: Install the Linode CLI - run: pip3 install ${{ env.pip_args }}linode-cli${{ env.version_extension }} + run: pip3 install ${pip_args}linode-cli${version_extension} shell: bash - name: Expose the Linode Token to the runner environment if: ${{ inputs.token != '' }} shell: bash - run: echo "LINODE_CLI_TOKEN=${{ inputs.token }}" >> "$GITHUB_ENV" + env: + TOKEN: ${{ inputs.token }} + run: echo "LINODE_CLI_TOKEN=$TOKEN" >> "$GITHUB_ENV" - name: Validate the CLI is installed if: ${{ inputs.token != '' }} From 007653f8c05eeb33c5a0c980d2aef6cf6a49d80f Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Fri, 31 Jul 2026 16:05:51 -0400 Subject: [PATCH 4/7] Add AGENTS.md --- AGENTS.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..97a05ba --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,26 @@ +# Agent Instructions + +## Repository Shape + +- This repository publishes a composite GitHub Action. Runtime behavior lives in [action.yml](action.yml); there is no source tree or generated build artifact. +- Treat [README.md](README.md) as the user-facing contract and [CONTRIBUTING.md](CONTRIBUTING.md) as the general contribution guide. +- The action supports Ubuntu-based runners. Do not imply macOS or Windows support without adding and passing coverage for those platforms. + +## Editing Rules + +- Treat action inputs and GitHub context values as untrusted. Never interpolate `${{ inputs.* }}` or `${{ github.* }}` directly into a `run:` script. Bind expressions through step-level `env:` entries, then reference shell variables with appropriate quoting or validation. +- Keep token masking before every other use of the token, and never print secret values. +- When adding or changing an input or runtime behavior, update [action.yml](action.yml), the relevant argument or example in [README.md](README.md), and coverage in [.github/workflows/test.yml](.github/workflows/test.yml) together. +- Preserve the existing composite-action and Bash style. Keep changes focused and avoid unrelated formatting churn. + +## Validation + +- There is no local build, unit-test, or lint command. The integration jobs in [.github/workflows/test.yml](.github/workflows/test.yml) are the executable test suite and run only on pushes. +- Tests invoke the checked-out action with `uses: ./` on `ubuntu-latest`. Authenticated scenarios require the repository's `LINODE_TOKEN` secret and network access. +- Add or adjust a focused integration scenario for each changed input path or installation mode. + +## Pull Requests + +- Target the default release branch, `v1`. +- PR titles must match `TPT-: ` unless an exemption label listed in [.github/workflows/validate-pr-title.yml](.github/workflows/validate-pr-title.yml) applies. Obtain a Jira ticket or explicit approval before creating a PR without that prefix. +- Follow [.github/pull_request_template.md](.github/pull_request_template.md) and keep each PR limited to one feature or fix. From f6f8b20646fa0bb17c376e22404ba7b97b6c59ec Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Fri, 31 Jul 2026 16:20:22 -0400 Subject: [PATCH 5/7] feat: Add dependabot configuration for GitHub Actions updates --- .github/dependabot.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..a728ab1 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" From e708719f57e5ac6e18fcf090a52a50b3cbb19dc0 Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Tue, 4 Aug 2026 17:17:42 -0400 Subject: [PATCH 6/7] Quote `linode-cli${version_extension}` --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 252efc5..3e289d0 100644 --- a/action.yml +++ b/action.yml @@ -68,7 +68,7 @@ runs: UPGRADE: ${{ inputs.upgrade }} - name: Install the Linode CLI - run: pip3 install ${pip_args}linode-cli${version_extension} + run: pip3 install ${pip_args}"linode-cli${version_extension}" shell: bash - name: Expose the Linode Token to the runner environment From b660609c056f8f3b4c16f84552bc207cc680aef8 Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Tue, 4 Aug 2026 17:40:27 -0400 Subject: [PATCH 7/7] fix: safely mask tokens and reject CR/LF on export --- README.md | 2 +- action.yml | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f2e034e..8464c0a 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This GitHub Action exposes the following arguments: | Name | Required | Default | Description | |-----------------|----------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `token` | No | None | The [Linode Personal Access Token](https://www.linode.com/docs/products/tools/api/guides/manage-api-tokens/) to authenticate the CLI with. | +| `token` | No | None | The [Linode Personal Access Token](https://www.linode.com/docs/products/tools/api/guides/manage-api-tokens/) to authenticate the CLI with. Must not contain carriage returns or newlines. | | `version` | No | latest | The version of the Linode CLI to install. | | `setup-python` | No | true | If true, Python will automatically be installed on the runner. If false, users are expected to have a functioning Python installation on their runner before running this action. | | `upgrade` | No | true | If true, Linode CLI and its dependencies will be automatically upgraded. (--upgrade) | diff --git a/action.yml b/action.yml index 3e289d0..80f7374 100644 --- a/action.yml +++ b/action.yml @@ -6,7 +6,7 @@ branding: color: 'orange' inputs: token: - description: 'The Linode API Personal Access Token to authenticate with.' + description: 'The Linode API Personal Access Token to authenticate with. Must not contain carriage returns or newlines.' version: description: 'The Linode CLI version to install.' default: latest @@ -26,7 +26,15 @@ runs: shell: bash env: TOKEN: ${{ inputs.token }} - run: echo "::add-mask::$TOKEN" + run: | + if [ -z "${TOKEN}" ]; then + exit 0 + fi + # Match actions/toolkit escapeData(): %, \r, \n + MASK_VALUE="${TOKEN//%/%25}" + MASK_VALUE="${MASK_VALUE//$'\r'/%0D}" + MASK_VALUE="${MASK_VALUE//$'\n'/%0A}" + echo "::add-mask::${MASK_VALUE}" - name: Setup Python 3 uses: actions/setup-python@v7 @@ -76,7 +84,12 @@ runs: shell: bash env: TOKEN: ${{ inputs.token }} - run: echo "LINODE_CLI_TOKEN=$TOKEN" >> "$GITHUB_ENV" + run: | + if [[ "${TOKEN}" == *$'\n'* || "${TOKEN}" == *$'\r'* ]]; then + echo "::error::token must not contain carriage returns or newlines" + exit 1 + fi + echo "LINODE_CLI_TOKEN=${TOKEN}" >> "${GITHUB_ENV}" - name: Validate the CLI is installed if: ${{ inputs.token != '' }}