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

Consume list-files #64

Closed
0xBradock opened this issue Jan 29, 2021 · 3 comments
Closed

Consume list-files #64

0xBradock opened this issue Jan 29, 2021 · 3 comments
Labels
question Further information is requested

Comments

@0xBradock
Copy link

0xBradock commented Jan 29, 2021

Hello,

We have a microservice architecture operating in a mono-repo configuration.

I would like to create 1 Github Action to lint/test/publish/... only the service that has changed.

I thought of using the list-files: shell, then consuming the result by iterating through the list and for each path executing a command. Something on the lines of: for (service in list-files); cd service && golangci-lint run.
We'll be only changing one service at a time, so most likely the list will only have one value.

The workflow detects correctly which services have been changed, but I'm not able to consume the list correctly.
Any help is much appreciated.

Thanks,


My repo looks like this:

.
└── .github
    └── workflows
        └── go.yml
├── README.md
├── go.mod
└── server
    ├── serviceone
    │   └── main.go
    ├── servicetwo
    │   └── main.go
    └── servicethree
        └── main.go

My go.yml looks like:

name: Lint Go code

on: [push, pull_request]

jobs:
  Lint:
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v2
      - name: Set up Go
        uses: actions/setup-go@v2
        with:
          go-version: 1.15
      - uses: dorny/paths-filter@v2
        id: changes
        with:
          filters: |
            server:
              - 'server/**'
          list-files: shell
      - name: Printing file changes
        run: |
          for val in ${steps.changes.outputs[@]}; do echo $val; done

I'm getting the following result after Github actions runs my workflow:

image

@dorny
Copy link
Owner

dorny commented Jan 29, 2021

Hello,

GitHub context variables are not mapped to shell variables (unless you set them as env variables).
GitHub workflow engine will instead do substitution before your shell command is executed.
You have to use ${{ <expression> }} syntax instead of ${<expression>}.

Next things is what is actually output of this actions. For your example it would be:

{
  "server": "true",
  "server_files": "\"server/pricinf/main.go\" \"server/sendmain/packGreet/logic.go\"",
  "changes": ["server"]
}

You wrote you are trying to get list of services which changed, but you can't get that directly out of this.
list-files option is useful mostly when you want to pass list of changed files directly as argument to linter.
If your linter operates on a whole folder I would chose different approach.

You could have for example this filter:

 with:
   filters: |
     pricing: 'server/pricing/**'
     sendmail: 'server/sendmail/**'

Afterwards you have several options:

  • use if conditions to selectively execute steps in service folders
  • use ${{ fromJson(needs.some-job.outputs.changes) }} as parameter for matrix job
  • use join(fromJson(steps.changes.outputs.changes), ' ') to transform changes output in JSON format to be usable in shell for loop. This requires your service names to not contain any special character or whitespace.

For example the last options would look like this:

 - name: Printing changed services
      run: |
        for val in ${{ join(fromJson(steps.changes.outputs.changes), ' ') }}; do echo $val; done

@dorny dorny added the question Further information is requested label Jan 29, 2021
@dorny
Copy link
Owner

dorny commented Feb 8, 2021

Hey @Kmelow, is your issue solved? Unless you have more issues/questions I will close this.

@0xBradock
Copy link
Author

Hello @dorny,

Thanks for the suggestion on filters above. The configuration is cleaner.

And I implemented a script using your suggested example and it is all good 👍

- name: Printing changed services
      run: |
        for val in ${{ join(fromJson(steps.changes.outputs.changes), ' ') }}; do echo $val; done

🙇 Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants