githubgithub-actions

github action expressions - split string


I'm trying to use a part of current branch name as a tag for publishing docker image in CI pipeline. The problem is that in my org, there is a convention to name branches like feature/foo, and docker tags can't contain slashes. So I want to split the string on '/' symbol and take the last part.

The full branch name, with slashes, should be in variable github.ref_name. Here is the expression I'm trying to evaluate: ${{ github.ref_name.split('/')[-1] }}.

I get this error: Unable to interpolate expression 'format('{0}', github.ref_name.split('/')[-1])': Failed to parse: unexpected token "(" while parsing arguments of function call. expecting ",", ")"

What are the options for manipulating strings in github actions expression? I didn't find it in docs https://docs.github.com/en/actions/learn-github-actions/expressions


Solution

  • IMPROVED:

    This technique doesn't need to bring in anything from the actions marketplace.

    Add this to steps: in an action:

          - name: Split branch name
            env:
              BRANCH: ${{ github.ref_name }}
            id: split
            run: echo "fragment=${BRANCH##*/}" >> $GITHUB_OUTPUT
    
    

    It captures the output of a shell command. The only necessary actions are setting github.ref_name to an environmental variable and using parameter expansion to get the part of the branch name you want.

    Because id is split, and name=fragment, you then reference your split string with steps.split.outputs.fragment. For example,

          # Another step
          - name: Test variable
            run: |
              echo ${{ steps.split.outputs.fragment }}
    

    Other parameter expansion features would be useful here, like #, %, and %% in addition to ##.

    220829: Final update

    Originally I spawned another process with $(echo ${BRANCH##*/}) but that is unnecessary. The variable can be directly referenced.


    ORIGINAL:

    I'm doing something essentially the same and using an action was the easiest temporary workaround, however I also would have preferred something built-in like a string-splitting expression. For now here is what worked.

          - uses: jungwinter/split@master
            id: branch
            with:
              msg: ${{ github.ref_name }}
              separator: "/"
              maxsplit: -1
    

    From its repo:

    Outputs

    • _0, _1, ..., _n: Each result of a split
      • According to metadata syntax of outputs, it has _ prefix
      • Currently, support only 100 splits
    • length: Length of the splits

    So, then I can reference each portion of the string with steps.branch.outputs._n, with branch being the id and n being the split index.

    I was looking for the first instead of the last value in the branch name, so I could set maxsplit to 1 and just take _0. In your case you might need to do some magic with checking length and choosing the index from there.