8

I use github actions for integration tests.

The problem is, that the tests should not run on multiple instances with the same configuration in parallel (the test would fail).

But, it can be run once with let's say configuration 1 and once with configuration 2 in parallel.

As this blog post describes, it is not possible to secure that a workflow does not run in parallel.

Is there any way to switch configurations, that configuration 1 and configuration 2 alternately?

In that case, it would not be that likely that the workflow workflows with the same configuration runs in parallel (I could add more configurations if needed).

For example, this could be done by a global and writable (for the workflow) variable that is alternately 1 or 2 and the workflow picks that configuration.

Example workflow(the secret confToSwitch should be switched):

name: test
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1
    - name: Set up JDK 1.8
      uses: actions/setup-java@v1
      with:
        java-version: 1.8
    - name: "load configuration"
      run: echo "configuration=$conf" >> ./conf
      env:
        conf: ${{ secrets.confToSwitch }}
    - name: "integration tests"
      run: "mvn -B integration-test"
dan1st
  • 12,568
  • 8
  • 34
  • 67
  • Can you show an example workflow that requires this? This could probably be solved by using matrix or conditional steps – smac89 Dec 12 '19 at 17:01
  • @smac89 I've edited it. – dan1st Dec 12 '19 at 17:10
  • What is the nature of your test that causes it to fail when run in parallel on two separate instances? Also what kind of value does `confToSwitch` contain and how does it help the test? – smac89 Dec 12 '19 at 17:22
  • It will login to a service with a token and send messages to that service. It tests if there are those messages sent from the self user and there are problems if it logs in multiple times using the same token in parallel. – dan1st Dec 12 '19 at 17:29
  • Have you considered using a matrix configuration? You can use your `tokens` as part of the matrix and when the job runs all the tokens will be used across different jobs. – smac89 Dec 12 '19 at 17:47
  • I don't know anything about matrix configuration but I could try – dan1st Dec 12 '19 at 17:50

1 Answers1

15

You can try a matrix configuration with:

name: test
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        token: [token1, token2, etc...]
    steps:
    - uses: actions/checkout@v1
    - name: Set up JDK 1.8
      uses: actions/setup-java@v1
      with:
        java-version: 1.8
    - name: "load configuration"
      run: echo "configuration=$conf" >> ./conf
      env:
        conf: ${{ matrix.token }}
    - name: "integration tests"
      run: "mvn -B integration-test"

This will create N jobs where N is the number of tokens in the list and each job with conf: ${{ matrix.token }} will resolve to a token in the list for the current job.


I think it may also be possible to store your tokens as secrets and setup the matrix like:

strategy:
  matrix:
    token: ["${{secrets.token1}}", "${{secrets.token2}}", etc...]

However, I haven't tested this.

EDIT

I found a trick to make the secrets tokens work:

  1. Create your secrets and call them token1, token2, etc
  2. Create your matrix configuration using the tokens i.e. the names of the secrets:
strategy:
  matrix:
    token: [token1, token2]
  1. In your job's env, create the following environment variable:
env:
  token: ${{secrets[matrix.token]}}
  1. Now the actual value for the token for each build matrix is stored inside the environment variable ${{env.token}} (when operating within an expression context) or $token (in bash).

The environment variable will still remain a secret, so you don't loose anything.

smac89
  • 39,374
  • 15
  • 132
  • 179
  • is this also possible with secret variables? – dan1st Dec 12 '19 at 18:06
  • @dan1st, I just commented that. I will test and get back to you on that – smac89 Dec 12 '19 at 18:07
  • @dan1st, looks like it is not possible. I get an error: `Unrecognized named-value: 'secrets'` – smac89 Dec 12 '19 at 18:21
  • @dan1st. I found a way to have it work. See the new edit – smac89 Dec 12 '19 at 18:41
  • Thanks, but I have one question: now the job is executed 2 times. Is it possible to use only execute it once? – dan1st Dec 12 '19 at 18:57
  • I mean that token1 is used and token2 when the workflow is executed again – dan1st Dec 12 '19 at 18:57
  • @dan1st you mean you want both tokens present in the same job? Well it can be done, but you have to test each token manually i.e. a new step for each token and specify the token. Unfortunately Github actions does not have substantial support for reusability of steps or workflows. See this other question: https://stackoverflow.com/questions/59230841/does-github-actions-have-templates – smac89 Dec 12 '19 at 19:39
  • I'll try to explain my problem: the workflow is executed on push events. If there are 2 pushes right after each other, it will result in the workflow running in parallel. – dan1st Dec 12 '19 at 19:44
  • I want another token for the second push. In other words, I want to use token1 the first time and token2 the second time the workflow runs. After that, the first token should be used. – dan1st Dec 12 '19 at 19:44
  • @dan1st what if there are three pushes at the same time? I don't think that's a good way of testing; it's too brittle. The matrix strategy has a [`max-parallel`](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idstrategymax-parallel) option with which you can use to limit the number of concurrent jobs. In your case, just to be safe, I would recommend you set it to a value of `1` so that only one job runs at a time and any subsequent pushes will have to wait – smac89 Dec 12 '19 at 20:00
  • Yes, this would help. I wanted to reduce the chance of conflicts. – dan1st Dec 12 '19 at 20:23