Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Differentiate between input parameter empty or not present #924

Open
rsenden opened this issue Jan 20, 2021 · 12 comments · May be fixed by #1176
Open

Differentiate between input parameter empty or not present #924

rsenden opened this issue Jan 20, 2021 · 12 comments · May be fixed by #1176
Labels
bug Something isn't working papercut Runner Bug Bug fix scope to the runner

Comments

@rsenden
Copy link

rsenden commented Jan 20, 2021

Current behavior:

  • If an input parameter is defined in action.yml (without default value), GitHub will set the INPUT_PARAMNAME environment variable to an empty value if the parameter is not present in the workflow

Expected behavior:

  • If an input parameter is defined in action.yml (without default value), GitHub should not set the INPUT_PARAMNAME environment variable to an empty value if the parameter is not present in the workflow

Possibly related issue for JavaScript actions: actions/toolkit#272

Resources that illustrate this issue:

As can be seen in the workflow output, results are different between running the Docker image directly or through the GitHub Action.

This can cause issues if a Docker image (or other action implementation) differentiates between 'empty' and 'not set'. If an action wants to set an empty value as the default value, then this should be done using the default property in the action definition.

Can you please get this fixed?

@rsenden rsenden added the bug Something isn't working label Jan 20, 2021
@rsenden rsenden changed the title Differentiate between input variable empty or not present Differentiate between input parameter empty or not present Jan 20, 2021
@hross
Copy link
Contributor

hross commented Mar 31, 2021

This is currently a low priority for us in terms of where it falls in our bug priority. I am marking it a papercut but I don't expect us to be able to get to fixing it soon.

@lucacome
Copy link

lucacome commented Sep 1, 2021

I just stumbled on this, any way those PRs are going to be merged anytime soon?

@shrink
Copy link

shrink commented Sep 1, 2021

@hross if anything is needed from my end to move the merge of my fixes forward, please let me know, happy to do any additional work required to get this fixed :-)

@rethab
Copy link
Contributor

rethab commented Feb 25, 2022

Hi @hross I'd like to bring this to your attention again. This problem is made worse in combination with reusable workflows:

Specifically, while the author of an action cannot distinguish between "no input passed" and "empty string passed", the runner does seem to distinguish between the two when deciding whether to use defaults: If an empty string is passed as an input, then the default value is not used, but when the input is omitted entirely, then the default is used.

Now consider reusable workflows. Imagine a main workflow that calls a reusable workflow which in turn calls an action. There is one input, which is passed all the way down to the action. If the main workflow doesn't specify the input to the reusable workflow, then the runner still turns that into an empty string. That empty string is then passed on to the action, where the default value is not used.

So it is the runner that turns "no input passed" into "empty string passed" and then it reaches the action where the default is not used. This makes it tricky to handle default values with reusable workflows.

Also cc @chrispat

Example

Action

name: Test
description: Test Action

inputs:
  greeting:
    required: false
    description: 'Greeting to use.'
    default: 'Hello'

runs:
  using: 'composite'
  steps:
    - run: echo ${{ inputs.greeting }} Earthling
      shell: bash

Partial Workflow

on:
  workflow_call:
    inputs:
      greeting:
        description: "The greeting to use"
        required: false
        type: string

jobs:
  greet:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: ./
        with:
          greeting: ${{ inputs.greeting }}

Main Workflow

jobs:
  greet:
    uses: rethab/actions-test-repo/.github/workflows/partial.yml@main

Output

image

@nikola-jokic nikola-jokic added the Runner Bug Bug fix scope to the runner label Apr 4, 2022
@sean-m-sullivan
Copy link

Hello @hross I've been looking into an issue with a Github marketplace action, and found that this also is an issue there. It is nearly if not completely impossible to evaluate an input argument as null without these changes going through. I highly support this PR to go through.

michalinacienciala added a commit to threshold-network/token-dashboard that referenced this issue Aug 18, 2022
In the workflow we're executing the `thesis/gcp-storage-bucket-action@v3.1.0`
action. One of its inputs is `bucket-path`, wich is an optional
input and is used to configure bucket path.

If in the workflow step executing the action we don't use the
`bucket-path` property, the action will set its `bocket-path` input to
the default value which is `.`. This is the value that we want to use
when workflow is triggered manually or by merge to main.
Previously we thought that setting the action to use
`bucket-name: ${{ github.head_ref }}` property would do the trick of
using `.` for `workflow_dispatch` and ``push` events and using
`head_ref` for `pull_request` events (because we thouth the default
value will be used when `bucket-name: ` (vithout a value) is used in
the action. But this turned out to not be truth. When we use
`bucket-name: ` the behavior is different than when we don't provide the
`bucket-name` property at all. In the first case we don't see the
`bucket-name` property in the runner's log, in the second case we see
the property populated with the default `.` value.
Not having `bucket-name` property in the runner results in wrong
behavior of the action (order of the inputs gets messed up and the
address of bucket gets resolved to gs://<BUCKETNAME>/<BUILDFOLDER>".

As a solution we add a `set-bucket-path` step which creates an output
which vallue is either `.` or `github.head_ref`, depending if the
latter is configured. We then use this output as value of `bucket-path`
parameter of action `thesis/gcp-storage-bucket-action@v3.1.0`.

Read more about how runner handles empty values here:
actions/runner#924.
michalinacienciala added a commit to threshold-network/token-dashboard that referenced this issue Aug 18, 2022
In the workflow we're executing the `thesis/gcp-storage-bucket-action@v3.1.0`
action. One of its inputs is `bucket-path`, wich is an optional
input and is used to configure bucket path.

If in the workflow step executing the action we don't use the
`bucket-path` property, the action will set its `bucket-path` input to
the default value which is `.`. This is the value that we want to use
when workflow is triggered manually or by merge to main.
Previously we thought that setting the action to use
`bucket-name: ${{ github.head_ref }}` property would do the trick of
using `.` for `workflow_dispatch` and `push` events and using
`head_ref` for `pull_request` events (because we thouth the default
value will be used when `bucket-name: ` (vithout a value) is used in
the action. But this turned out to not be truth. When we use
`bucket-name: ` the behavior is different than when we don't provide the
`bucket-name` property at all. In the first case we don't see the
`bucket-name` property in the runner's log, in the second case we see
the property populated with the default `.` value.
Not having `bucket-name` property in the runner results in wrong
behavior of the action (order of the inputs gets messed up and the
address of bucket gets resolved to gs://<BUCKETNAME>/<BUILDFOLDER>".

As a solution we add a `set-bucket-path` step which creates an output
which vallue is either `.` or `github.head_ref`, depending if the
latter is configured. We then use this output as value of `bucket-path`
parameter of action `thesis/gcp-storage-bucket-action@v3.1.0`.

Read more about how runner handles empty values here:
actions/runner#924.
michalinacienciala added a commit to threshold-network/token-dashboard that referenced this issue Aug 18, 2022
In the workflow we're executing the `thesis/gcp-storage-bucket-action@v3.1.0`
action. One of its inputs is `bucket-path`, which is an optional
input and is used to configure bucket path.

If in the workflow step executing the action we don't use the
`bucket-path` property, the action will set its `bucket-path` input to
the default value which is `.`. This is the value that we want to use
when workflow is triggered manually or by merge to main.
Previously we thought that setting the action to use
`bucket-name: ${{ github.head_ref }}` property would do the trick of
using `.` for `workflow_dispatch` and `push` events and using
`head_ref` for `pull_request` events (because we thougt the default
value will be used when `bucket-name: ` (without a value) is used in
the action. But this turned out to not be truth. When we use
`bucket-name: ` the behavior is different than when we don't provide the
`bucket-name` property at all. In the first case we don't see the
`bucket-name` property in the runner's log, in the second case we see
the property populated with the default `.` value.
Not having `bucket-name` property in the runner results in wrong
behavior of the action (order of the inputs gets messed up and the
address of bucket gets resolved to gs://<BUCKETNAME>/<BUILDFOLDER>".

As a solution we add a `set-bucket-path` step which creates an output
which value is either `.` or `github.head_ref`, depending if the
latter is configured. We then use this output as value of `bucket-path`
parameter of action `thesis/gcp-storage-bucket-action@v3.1.0`.

Read more about how runner handles empty values here:
actions/runner#924.
michalinacienciala added a commit to threshold-network/token-dashboard that referenced this issue Aug 18, 2022
In the workflow we're executing the `thesis/gcp-storage-bucket-action@v3.1.0`
action. One of its inputs is `bucket-path`, which is an optional
input and is used to configure bucket path.

If in the workflow step executing the action we don't use the
`bucket-path` property, the action will set its `bucket-path` input to
the default value which is `.`. This is the value that we want to use
when workflow is triggered manually or by merge to main.
Previously we thought that setting the action to use
`bucket-name: ${{ github.head_ref }}` property would do the trick of
using `.` for `workflow_dispatch` and `push` events and using
`head_ref` for `pull_request` events (because we thougt the default
value will be used when `bucket-name: ` (without a value) is used in
the action. But this turned out to not be truth. When we use
`bucket-name: ` the behavior is different than when we don't provide the
`bucket-name` property at all. In the first case we don't see the
`bucket-name` property in the runner's log, in the second case we see
the property populated with the default `.` value.
Not having `bucket-name` property in the runner results in wrong
behavior of the action (order of the inputs gets messed up and the
address of bucket gets resolved to gs://<BUCKETNAME>/<BUILDFOLDER>".

As a solution we add a `set-bucket-path` step which creates an output
which value is either `.` or `github.head_ref`, depending if the
latter is configured. We then use this output as value of `bucket-path`
parameter of action `thesis/gcp-storage-bucket-action@v3.1.0`.

Read more about how runner handles empty values here:
actions/runner#924.
nkuba added a commit to threshold-network/token-dashboard that referenced this issue Aug 18, 2022
…o-bucket-action

Specify `bucket-path` when `github.head_ref` is not set

In the workflow we're executing the `thesis/gcp-storage-bucket-action@v3.1.0`
action. One of its inputs is `bucket-path`, which is an optional
input and is used to configure bucket path.

If in the workflow step executing the action we don't use the
`bucket-path` property, the action will set its `bucket-path` input to
the default value which is `.`. This is the value that we want to use
when workflow is triggered manually or by merge to main.
Previously we thought that setting the action to use
`bucket-name: ${{ github.head_ref }}` property would do the trick of
using `.` for `workflow_dispatch` and `push` events and using
`head_ref` for `pull_request` events (because we thougt the default
value will be used when `bucket-name: ` (without a value) is used in
the action. But this turned out to not be truth. When we use
`bucket-name: ` the behavior is different than when we don't provide the
`bucket-name` property at all. In the first case we don't see the
`bucket-name` property in the runner's log, in the second case we see
the property populated with the default `.` value.
Not having `bucket-name` property in the runner results in wrong
behavior of the action (order of the inputs gets messed up and the
address of bucket gets resolved to gs://<BUCKETNAME>/<BUILDFOLDER>".

As a solution we add a `set-bucket-path` step which creates an output
which value is either `.` or `github.head_ref`, depending if the
latter is configured. We then use this output as value of `bucket-path`
parameter of action `thesis/gcp-storage-bucket-action@v3.1.0`.

Read more about how runner handles empty values here:
actions/runner#924.
georgeweiler pushed a commit to threshold-network/token-dashboard that referenced this issue Sep 8, 2022
In the workflow we're executing the `thesis/gcp-storage-bucket-action@v3.1.0`
action. One of its inputs is `bucket-path`, which is an optional
input and is used to configure bucket path.

If in the workflow step executing the action we don't use the
`bucket-path` property, the action will set its `bucket-path` input to
the default value which is `.`. This is the value that we want to use
when workflow is triggered manually or by merge to main.
Previously we thought that setting the action to use
`bucket-name: ${{ github.head_ref }}` property would do the trick of
using `.` for `workflow_dispatch` and `push` events and using
`head_ref` for `pull_request` events (because we thougt the default
value will be used when `bucket-name: ` (without a value) is used in
the action. But this turned out to not be truth. When we use
`bucket-name: ` the behavior is different than when we don't provide the
`bucket-name` property at all. In the first case we don't see the
`bucket-name` property in the runner's log, in the second case we see
the property populated with the default `.` value.
Not having `bucket-name` property in the runner results in wrong
behavior of the action (order of the inputs gets messed up and the
address of bucket gets resolved to gs://<BUCKETNAME>/<BUILDFOLDER>".

As a solution we add a `set-bucket-path` step which creates an output
which value is either `.` or `github.head_ref`, depending if the
latter is configured. We then use this output as value of `bucket-path`
parameter of action `thesis/gcp-storage-bucket-action@v3.1.0`.

Read more about how runner handles empty values here:
actions/runner#924.
georgeweiler pushed a commit to threshold-network/token-dashboard that referenced this issue Sep 8, 2022
…o-bucket-action

Specify `bucket-path` when `github.head_ref` is not set

In the workflow we're executing the `thesis/gcp-storage-bucket-action@v3.1.0`
action. One of its inputs is `bucket-path`, which is an optional
input and is used to configure bucket path.

If in the workflow step executing the action we don't use the
`bucket-path` property, the action will set its `bucket-path` input to
the default value which is `.`. This is the value that we want to use
when workflow is triggered manually or by merge to main.
Previously we thought that setting the action to use
`bucket-name: ${{ github.head_ref }}` property would do the trick of
using `.` for `workflow_dispatch` and `push` events and using
`head_ref` for `pull_request` events (because we thougt the default
value will be used when `bucket-name: ` (without a value) is used in
the action. But this turned out to not be truth. When we use
`bucket-name: ` the behavior is different than when we don't provide the
`bucket-name` property at all. In the first case we don't see the
`bucket-name` property in the runner's log, in the second case we see
the property populated with the default `.` value.
Not having `bucket-name` property in the runner results in wrong
behavior of the action (order of the inputs gets messed up and the
address of bucket gets resolved to gs://<BUCKETNAME>/<BUILDFOLDER>".

As a solution we add a `set-bucket-path` step which creates an output
which value is either `.` or `github.head_ref`, depending if the
latter is configured. We then use this output as value of `bucket-path`
parameter of action `thesis/gcp-storage-bucket-action@v3.1.0`.

Read more about how runner handles empty values here:
actions/runner#924.
@SushmitaGoswami
Copy link

Do we have a solution for this?

@abower-digimarc
Copy link

Hello, this is an issue for me as well.

I have an action, I want to specify a default value.

However, as described by @rethab here, when I use an action with reusable workflows, 'no input' is changed to 'empty string' above the action, thus the action never uses the default value.

Not only is this not well documented, resulting in unexpected behavior (i.e., the default value never gets consumed by my action), it does seem a bug.

@druskus20
Copy link

This is also a problem for me, which renders default values almost useless in reusable workflows or composite actions.
The fact that there's no distinction between these two means that we need to propagate default values for input parameters throughout the chain of actions.

@dbsanfte
Copy link

This is a very nasty gotcha for anyone trying to build reusable workflows across a Github organisation. We are an enterprise customer and would greatly appreciate you fixing this.

@kkurczewski
Copy link

I don't know why this is marked papercut, it is second most voted issue and it isn't a debatable feature but a freaking bug. And reported back in 2021!

After a honeymoon with Github Actions I start to think that I can't wholeheartedly recommend it in my next projects because it is basically dead project and is deaf to its clients. Better to put money somewhere else or roll something open source.

@shrink
Copy link

shrink commented Feb 18, 2024

@TingluoHuang I think this issue has slipped through the cracks as @hross doesn't appear to work at GitHub any more. I'm not sure who is responsible for the runner, but as you're the most active contributor to actions/runner, are you able to take a look at this and determine whether it can be addressed? There's an open Pull Request I created a few years ago with a proposed fix (#1176) and a companion Pull Request for actions/toolkit (actions/toolkit#849). If this isn't a bug, or it's bug that isn't going to be fixed, could you close this issue as won't fix (or equivalent)? Thank you.

@flowchartsman
Copy link

flowchartsman commented Mar 21, 2024

Here's a more concrete example of where this feature would save people a lot of frustration and pain:

I was attempting to use google-github-actions/auth to set up google cloud credentials to upload release artifacts. The documentation states that you can provide one of workload_identity_provider or credentials_json in the parameters, which I was attempting to do via a secret:

    - uses: 'google-github-actions/auth@v2'
      with:
        credentials_json: '${{ secrets.EXAMPLE_CREDENTIALS }}'

This did not work, and the root cause ended up being that I had defined this particular secret in an environment, but had neglected to set the environment on the job; however, because there is no meaningful way to detect the difference between an empty parameter and none at all, it was treated as if I hadn't provided the parameter, leading to a very misleading error of:

 the GitHub Action workflow must specify exactly one of "workload_identity_provider" or "credentials_json"! If you are specifying input values via GitHub secrets, ensure the secret is being injected into the environment. By default, secrets are not passed to workflows triggered from forks, including Dependabot.

Which is about as helpful as a kick in the teeth when someone is looking at a YAML workflow definition that appears to explicitly declare a parameter and a secret value to put in it. In this case it's made even worse thanks to the ambiguous meaning of "environment" and the admonition to "ensure the secret is being injected into the environment" -- do they mean github environments or environment variables? The term "inject" is also ambiguous and seems to imply using an environment variable, which is actually incorrect here.

I know it is not github's responsibility to police error messages in 3rd-party actions; however, if this feature were available actions could at least have the ability to provide more meaningful errors.

Having to hunt this down was a deeply unpleasant exercise and wasted a lot of time, whereas a more meaningful error message such as:

credentials_json provided, but the value was empty; your secret may be undefined or exist within an environment, in which case you need to attach the environment to the workflow

from the action or:

found a secret "credentials_json" that is empty; is it in a different environment (etc, etc)

from the actions runner would have saved me time and stress.

There is, of course, no guarantee that an action would take advantage of this feature, but it absolutely should have the ability to do so, if it wants.

ChrisBAshton added a commit to alphagov/govuk-browser-extension that referenced this issue May 29, 2024
This will resolve the alert at https://gds.slack.com/archives/C02L13S214K/p1714381348726429.

NB, this took a bit of effort! We were [seeing](https://github.com/alphagov/govuk-browser-extension/actions/runs/9283183060/job/25542847886?pr=196) an error with the default code analysis:

```
Extracting javascript
Extracting ruby
Finalizing javascript
Finalizing ruby
  /opt/hostedtoolcache/CodeQL/2.17.1/x64/codeql/codeql database finalize --finalize-dataset --threads=4 --ram=14567 /home/runner/work/_temp/codeql_databases/ruby
  CodeQL detected code written in JavaScript/TypeScript, but not any written in Ruby. Confirm that there is some source code for Ruby in the project. For more information, review our troubleshooting guide at https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build .
  Error: Encountered a fatal error while running "/opt/hostedtoolcache/CodeQL/2.17.1/x64/codeql/codeql database finalize --finalize-dataset --threads=4 --ram=14567 /home/runner/work/_temp/codeql_databases/ruby". Exit code was 32 and last log line was: CodeQL detected code written in JavaScript/TypeScript, but not any written in Ruby. Confirm that there is some source code for Ruby in the project. For more information, review our troubleshooting guide at https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build . See the logs for more details.
```

We explored configuring the [reusable workflow](https://github.com/alphagov/govuk-infrastructure/blob/main/.github/workflows/codeql-analysis.yml) to take a `languages` input, but there [doesn't seem to be a way of defaulting to 'undefined'](actions/runner#924) if the parameter isn't passed, meaning we'd have to set a default of, say, 'ruby'. This would break the workflow for repos that may already be working with both Ruby and JS, where they'd be forced to pass the `languages` parameter now.

We also explored setting up CodeQL directly within the GitHub UI and explicitly opting out of Ruby to have JS only, but the reusable workflow still does a language detection and runs both JS and Ruby scans (the "JS only" scan appears as a separate job called "CodeQL / Analyze (javascript-typescript) (dynamic)"):

![Screenshot 2024-05-29 at 09 50 26](https://github.com/alphagov/govuk-browser-extension/assets/5111927/114bb17b-ac2e-4f42-8560-a0df69a49178)

Eventually, on closer inspection, we found that only ruby in this
project was a disused Rakefile, so we removed it in #198. Now the
CodeQL scan passes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working papercut Runner Bug Bug fix scope to the runner
Projects
None yet
Development

Successfully merging a pull request may close this issue.