Conditional step for the last value in (dynamically generated) matrix of Github Actions only

Viewed 18

I'm trying to conditionally run the job step for the last value of the matrix only.

For demo purposes, the simplified actions file follows.

Please note the simplification: matrix values are static in sample, but I need the solution to work without constants (as the case I'm solving generates these dynamically):

on:
  push:
    branches:
      - main

jobs:
  example_matrix:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        version: [1,2,3]
    steps:
      - run: |
          echo Matrix value: "${{ matrix.value }}"
      - if: ${{fromJson(matrix.version[-1])}} == ${{ matrix.value }}
        run: |
          echo Matrix value (latest): "${{ matrix.value }}"

Please note, the if condition is of my interest, to be corrected. I want it to run for the last element of the matrix.version array only.

Current output:

Error: The template is not valid. Newtonsoft.Json.JsonReaderException: Error reading JToken from JsonReader. Path '', line 0, position 0.
   at Newtonsoft.Json.Linq.JToken.ReadFrom(JsonReader reader, JsonLoadSettings settings)
   at Newtonsoft.Json.Linq.JToken.ReadFrom(JsonReader reader)
   at GitHub.DistributedTask.Expressions2.Sdk.Functions.FromJson.EvaluateCore(EvaluationContext context, ResultMemory& resultMemory)
   at GitHub.DistributedTask.Expressions2.Sdk.ExpressionNode.Evaluate(EvaluationContext context)
   at GitHub.DistributedTask.Expressions2.Sdk.Functions.Format.FormatResultBuilder.<>c__DisplayClass3_0.<Append>b__0()
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.get_Value()
   at GitHub.DistributedTask.Expressions2.Sdk.Functions.Format.FormatResultBuilder.<>c.<ToString>b__1_0(Object obj)
   at System.Linq.Enumerable.SelectListIterator`2.MoveNext()
   at System.String.Join(String separator, IEnumerable`1 values)
   at GitHub.DistributedTask.Expressions2.Sdk.Functions.Format.FormatResultBuilder.ToString()
   at GitHub.DistributedTask.Expressions2.Sdk.Functions.Format.EvaluateCore(EvaluationContext context, ResultMemory& resultMemory)
   at GitHub.DistributedTask.Expressions2.Sdk.ExpressionNode.Evaluate(EvaluationContext context)
   at GitHub.DistributedTask.Expressions2.Sdk.Operators.And.EvaluateCore(EvaluationContext context, ResultMemory& resultMemory)
   at GitHub.DistributedTask.Expressions2.Sdk.ExpressionNode.Evaluate(EvaluationContext context)
   at GitHub.DistributedTask.Expressions2.Sdk.ExpressionNode.GitHub.DistributedTask.Expressions2.IExpressionNode.Evaluate(ITraceWriter trace, ISecretMasker secretMasker, Object state, EvaluationOptions options)
   at GitHub.DistributedTask.ObjectTemplating.Tokens.TemplateToken.EvaluateTemplateToken(TemplateContext context, String expression, Int32& bytes)
   at GitHub.DistributedTask.ObjectTemplating.Tokens.BasicExpressionToken.EvaluateTemplateToken(TemplateContext context, Int32& bytes)
   at GitHub.DistributedTask.ObjectTemplating.TemplateUnraveler.RootBasicExpression()

1 Answers

OK, haven't found a way to achieve it via conditional step => ended up with the 3 actions in total, where one publishes full array in 1 variable and last element in another one. job2 creates the matrix on full array and job3 on the last element only.

See my solution:

on:
  push:
    branches:
      - main

jobs:
  job1:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.matrix.outputs.matrix }}
      last: ${{ steps.matrix.outputs.last }}
    steps:
      - id: matrix
        run: |
          echo "::set-output name=matrix::[\"1\",\"2\"]"
          echo "::set-output name=last::[\"2\"]"

  job2:
    needs: [ job1 ]
    runs-on: ubuntu-latest
    strategy:
      matrix:
        value: ${{fromJson(needs.job1.outputs.matrix)}}
    steps:
      - run: |
          echo Current: "${{ matrix.value }}"

  job3:
    needs: [ job1 ]
    runs-on: ubuntu-latest
    strategy:
      matrix:
        value: ${{fromJson(needs.job1.outputs.last)}}
    steps:
      - run: |
          echo Current: "${{ matrix.value }}"
Related