diff --git a/.github/workflows/selftest.yml b/.github/workflows/selftest.yml index 06798f2..d213d33 100644 --- a/.github/workflows/selftest.yml +++ b/.github/workflows/selftest.yml @@ -32,6 +32,7 @@ jobs: id: sigstore-python with: inputs: ./test/artifact.txt + internal-be-careful-debug: true - name: Check outputs shell: bash run: | @@ -55,6 +56,7 @@ jobs: id: sigstore-python with: inputs: ${{ matrix.input }} + internal-be-careful-debug: true - name: Check failure env: XFAIL: ${{ steps.sigstore-python.outcome == 'failure' }} @@ -75,6 +77,7 @@ jobs: with: inputs: ./test/artifact.txt staging: true + internal-be-careful-debug: true - name: Check outputs run: | [[ -f ./test/artifact.txt.sigstore ]] || exit 1 @@ -90,6 +93,61 @@ jobs: with: inputs: ./test/*.txt staging: true + internal-be-careful-debug: true + - name: Check outputs + run: | + [[ -f ./test/artifact.txt.sigstore ]] || exit 1 + [[ -f ./test/artifact1.txt.sigstore ]] || exit 1 + [[ -f ./test/artifact2.txt.sigstore ]] || exit 1 + + selftest-xfail-glob-input-expansion: + runs-on: ubuntu-latest + env: + TEST_DIR: test + if: (github.event_name != 'pull_request') || !github.event.pull_request.head.repo.fork + steps: + - uses: actions/checkout@v3 + - name: Sign artifacts and publish signatures + continue-on-error: true + uses: ./ + id: sigstore-python + with: + # This should fail since we should never directly expand ${TEST_DIR}; + # the user should have to pre-expand it for us. + inputs: ./${TEST_DIR}/*.txt + staging: true + internal-be-careful-debug: true + - name: Check failure + env: + XFAIL: ${{ steps.sigstore-python.outcome == 'failure' }} + JOB_NAME: ${{ github.job }} + run: | + echo "xfail ${JOB_NAME}: ${XFAIL}" + + [[ "${XFAIL}" == "true" ]] || { >&2 echo "expected step to fail"; exit 1; } + + selftest-glob-multiple: + runs-on: ubuntu-latest + if: (github.event_name != 'pull_request') || !github.event.pull_request.head.repo.fork + steps: + - uses: actions/checkout@v3 + - name: Sign artifacts and publish signatures + uses: ./ + id: sigstore-python + with: + inputs: ./test/artifact*.txt ./test/another*.txt ./test/subdir/*.txt + staging: true + internal-be-careful-debug: true + - name: Check outputs + run: | + [[ -f ./test/artifact.txt.sigstore ]] || exit 1 + [[ -f ./test/artifact1.txt.sigstore ]] || exit 1 + [[ -f ./test/artifact2.txt.sigstore ]] || exit 1 + [[ -f ./test/another1.txt.sigstore ]] || exit 1 + [[ -f ./test/another2.txt.sigstore ]] || exit 1 + [[ -f ./test/subdir/hello1.txt.sigstore ]] || exit 1 + [[ -f ./test/subdir/hello2.txt.sigstore ]] || exit 1 + [[ -f ./test/subdir/hello3.txt.sigstore ]] || exit 1 selftest-upload-artifacts: runs-on: ubuntu-latest @@ -103,6 +161,7 @@ jobs: inputs: ./test/artifact.txt staging: true upload-signing-artifacts: true + internal-be-careful-debug: true - uses: actions/download-artifact@v3 with: name: "signing-artifacts-${{ github.job }}" @@ -127,6 +186,7 @@ jobs: certificate: ./test/custom_certificate.crt bundle: ./test/custom_bundle.sigstore staging: true + internal-be-careful-debug: true - name: Check outputs run: | [[ -f ./test/custom_signature.sig ]] || exit 1 @@ -147,6 +207,7 @@ jobs: verify-cert-identity: https://github.com/sigstore/gh-action-sigstore-python/.github/workflows/selftest.yml@${{ github.ref }} verify-oidc-issuer: https://token.actions.githubusercontent.com staging: true + internal-be-careful-debug: true selftest-xfail-verify-missing-options: runs-on: ubuntu-latest @@ -183,6 +244,8 @@ jobs: verify-oidc-issuer: ${{ matrix.config.verify-oidc-issuer }} verify-cert-identity: ${{ matrix.config.verify-cert-identity }} staging: true + internal-be-careful-debug: true + - name: Check failure env: XFAIL: ${{ steps.sigstore-python.outcome == 'failure' }} @@ -215,6 +278,7 @@ jobs: inputs: ./test/artifact.txt identity-token: ${{ steps.get-oidc-token.outputs.identity-token }} staging: true + internal-be-careful-debug: true all-selftests-pass: if: always() @@ -224,6 +288,7 @@ jobs: - selftest-xfail-invalid-inputs - selftest-staging - selftest-glob + - selftest-glob-multiple - selftest-upload-artifacts - selftest-custom-paths - selftest-verify diff --git a/README.md b/README.md index ce986a7..ce17a51 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ jobs: - uses: actions/checkout@v3 - name: install run: python -m pip install . - - uses: sigstore/gh-action-sigstore-python@v2.0.0 + - uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt ``` @@ -53,7 +53,7 @@ provided. To sign one or more files: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file0.txt file1.txt file2.txt ``` @@ -61,11 +61,15 @@ To sign one or more files: The `inputs` argument also supports file globbing: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: ./path/to/inputs/*.txt ``` +> [!NOTE]\ +> In versions of this action before 2.0.0, the `inputs` setting allowed for shell expansion. +> This was unintentional, and was removed with 2.0.0. + ### `identity-token` **Default**: Empty (the GitHub Actions credential will be used) @@ -74,7 +78,7 @@ The `identity-token` setting controls the OpenID Connect token provided to Fulci workflow will use the credentials found in the GitHub Actions environment. ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt identity-token: ${{ IDENTITY_TOKEN }} # assigned elsewhere @@ -90,7 +94,7 @@ Server during OAuth2. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt oidc-client-id: alternative-sigstore-id @@ -106,7 +110,7 @@ Connect Server during OAuth2. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt oidc-client-secret: alternative-sigstore-secret @@ -122,7 +126,7 @@ when signing multiple input files. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt signature: custom-signature-filename.sig @@ -131,7 +135,7 @@ Example: However, this example is invalid: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file0.txt file1.txt file2.txt signature: custom-signature-filename.sig @@ -147,7 +151,7 @@ work when signing multiple input files. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt certificate: custom-certificate-filename.crt @@ -156,7 +160,7 @@ Example: However, this example is invalid: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file0.txt file1.txt file2.txt certificate: custom-certificate-filename.crt @@ -172,7 +176,7 @@ when signing multiple input files. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt bundle: custom-bundle.sigstore @@ -181,7 +185,7 @@ Example: However, this example is invalid: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file0.txt file1.txt file2.txt certificate: custom-bundle.sigstore @@ -197,7 +201,7 @@ from. This setting cannot be used in combination with the `staging` setting. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt fulcio-url: https://fulcio.sigstage.dev @@ -213,7 +217,7 @@ cannot be used in combination with the `staging` setting. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt rekor-url: https://rekor.sigstage.dev @@ -229,7 +233,7 @@ in combination with the `staging` setting. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt ctfe: ./path/to/ctfe.pub @@ -245,7 +249,7 @@ be used in combination with `staging` setting. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt ctfe: ./path/to/rekor.pub @@ -261,7 +265,7 @@ instead of the default production instances. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt staging: true @@ -284,7 +288,7 @@ and `verify-oidc-issuer` settings. Failing to pass these will produce an error. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt verify: true @@ -307,7 +311,7 @@ This setting may only be used in conjunction with `verify-oidc-issuer`. Supplying it without `verify-oidc-issuer` will produce an error. ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt verify: true @@ -332,7 +336,7 @@ Supplying it without `verify-cert-identity` will produce an error. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt verify: true @@ -354,7 +358,7 @@ workflow artifact retention period is used. Example: ```yaml -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt upload-signing-artifacts: true @@ -382,7 +386,7 @@ permissions: # ... -- uses: sigstore/gh-action-sigstore-python@v2.0.0 +- uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt release-signing-artifacts: true @@ -409,7 +413,7 @@ permissions: Example: ```yaml - - uses: sigstore/gh-action-sigstore-python@v2.0.0 + - uses: sigstore/gh-action-sigstore-python@v2.0.1 with: inputs: file.txt internal-be-careful-debug: true diff --git a/action.py b/action.py index 23044f5..2374c82 100755 --- a/action.py +++ b/action.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # Copyright 2022 The Sigstore Authors # @@ -201,7 +201,15 @@ def _fatal_help(msg): if input_.startswith("-"): _fatal_help(f"input {input_} looks like a flag") - files = [Path(f).resolve() for f in glob(input_)] + # NOTE: We use a set here to deduplicate inputs, in case a glob expands + # to the same input multiple times. + files = {Path(f).resolve() for f in glob(input_)} + + # Prevent empty glob expansions, rather than silently allowing them. + # Either behavior is technically correct but an empty glob indicates + # user confusion, so we fail for them. + if not files: + _fatal_help(f"input {input_} doesn't expand to one or more filenames") for file_ in files: if not file_.is_file(): diff --git a/action.yml b/action.yml index a6fa96a..b20d943 100644 --- a/action.yml +++ b/action.yml @@ -102,6 +102,8 @@ runs: run: | # NOTE: Sourced, not executed as a script. source "${GITHUB_ACTION_PATH}/setup/setup.bash" + env: + GHA_SIGSTORE_PYTHON_INTERNAL_BE_CAREFUL_DEBUG: "${{ inputs.internal-be-careful-debug }}" shell: bash - name: Run sigstore-python diff --git a/setup/setup.bash b/setup/setup.bash index 498a8e5..ee645bb 100644 --- a/setup/setup.bash +++ b/setup/setup.bash @@ -21,6 +21,15 @@ die() { exit 1 } +debug() { + if [[ "${GHA_SIGSTORE_PYTHON_INTERNAL_BE_CAREFUL_DEBUG}" = "true" ]]; then + echo -e "\033[93mDEBUG: ${1}\033[0m" + fi +} + +debug "Python: $(python -V)" +debug "pip: $(python -m pip --version)" + # NOTE: This file is meant to be sourced, not executed as a script. if [[ "${0}" == "${BASH_SOURCE[0]}" ]]; then die "Internal error: setup harness was executed instead of being sourced?" diff --git a/test/another1.txt b/test/another1.txt new file mode 100644 index 0000000..730100b --- /dev/null +++ b/test/another1.txt @@ -0,0 +1 @@ +Another input. diff --git a/test/another2.txt b/test/another2.txt new file mode 100644 index 0000000..666e074 --- /dev/null +++ b/test/another2.txt @@ -0,0 +1 @@ +Yet another input. diff --git a/test/subdir/hello1.txt b/test/subdir/hello1.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/subdir/hello2.txt b/test/subdir/hello2.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/subdir/hello3.txt b/test/subdir/hello3.txt new file mode 100644 index 0000000..e69de29