Github action to validate yaml files using Yamllint - yaml

I'm adding a github action to validate my yaml files using yamllint
By default, when the length of a line surpasses 80 characters, yamllint will output an error like the following one:
Error: 5:81 [line-length] line too long (101 > 80 characters)
Is there by any chance a way to override the line-length which is 80 by default?
This can be done on the terminal using this syntax:
yamllint -d "{extends: relaxed, rules: {line-length: {max: 120}}}" main.yml but I can't find a way to apply the same thing on my github action.
This is what my github action looks like
name: Validate Yaml Files Format
on: [pull_request]
jobs:
validate-yaml:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
- name: Yamllint
uses: karancode/yamllint-github-action#master
with:
yamllint_strict: false
yamllint_comment: true
env:
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}

you could use the yamllint_config_datapath params as described in the input doc of the github action, as example:
- name: Yamllint
uses: karancode/yamllint-github-action#master
with:
yamllint_strict: false
yamllint_comment: true
yamllint_config_datapath: '{extends: relaxed, rules: {line-length: {max: 120}}}'

Related

Parametrise uses parameter in GitHub Actions

How I can pass parameter inputs.custom to this actions code:
jobs:
test-custom:
name: Test Custom
uses: ./.github/workflows/work4-${{ inputs.custom }}.yml
Fully working example:
First workflow work1-build.yml:
name: Start workflow fail
on: [push]
jobs:
build-fail:
name: Build with other workflow
uses: ./.github/workflows/work3-build-fail.yml
with:
custom: custom-name1
Second workflow work3-build-fail.yml:
name: Build fail with input test
on:
workflow_call:
inputs:
custom:
description: Some custom string
required: true
type: string
jobs:
test-custom:
name: Test Custom
uses: ./.github/workflows/work4-${{ inputs.custom }}.yml
Third workflow work4-custom-name1.yml
name: Custom 1
on:
workflow_call
jobs:
Explore-GitHub-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "IN CUSTOM 1"
Example above make GitHub respond with an error:
Invalid workflow file
error parsing called workflow
".github/workflows/work1-build.yml"
-> "./.github/workflows/work3-build-fail.yml" (source branch with sha:720087c8794e76f52277f9b1229b44ea65ab89d5)
--> "./.github/workflows/work4-${{ inputs.custom }}.yml"
: failed to fetch workflow: workflow was not found.
I can successfully add ${{ inputs.custom }} to:
test-print:
runs-on: ubuntu-latest
name: Print input
steps:
- name: Step print input
run: echo ${{ inputs.custom }}
Docs doesn't contain any examples with uses parametrisation:
https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsuses
I found documentation that proves this isn't possible. There is no supporting info stating that the uses key has access to any contexts.
See: https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
I believe this is an architectural limitation of GitHub Actions, it appears they want to resolve all workflows/actions at the start of all jobs and thus dynamic resolution isn't possible.

Can't checkout the same repo multiple times in a pipeline

I have self-hosted agents on multiple environments that I am trying to run the same build/deploy processes on. I would like to be able to deploy the same code from a single repo to multiple systems concurrently. Thus, I have created an "overhead" pipeline, and several "processes" pipeline templates. Everything seems to be going very well, except for when I try to perform checkouts of the same repo twice in the same pipeline execution. I get the following error:
An error occurred while loading the YAML build pipeline. An item with the same key has already been added.
I would really like to be able to just click ONE button to trigger a main pipeline that calls all the templates requires and gives the parameters needed to get all my jobs done at once. I could of course define this "overhead" pipeline and then queue up as many instances as I need of it per systems that I need to deploy to, but I'm lazy, hence why I'm using pipelines!
As soon as I remove the checkout from Common.yml, the validation succeeds without any issues. If I keep the checkout in there but only call the Common.yml once for the entire Overhead pipeline, then it succeeds without any issues as well. But the problem is: I need to pull the contents of the repo to EACH of my agents that are running on completely separate environments that are in no way ever able to talk to each other (can't pull the information to one agent and have it do some sort of a "copy" to all the other agent locations.....).
Any assistance is very much welcomed, thank you!
The following is my "overhead" pipeline:
# azure-pipelines.yml
trigger:
none
parameters:
- name: vLAN
type: string
default: 851
values:
- 851
- 1105
stages:
- stage: vLAN851
condition: eq('${{ parameters.vLAN }}', '851')
pool:
name: xxxxx
demands:
- vLAN -equals 851
jobs:
- job: Common_851
steps:
- template: Procedures/Common.yml
- job: Export_851
dependsOn: Common_851
steps:
- template: Procedures/Export.yml
parameters:
Server: ABTS-01
- stage: vLAN1105
condition: eq('${{ parameters.vLAN }}', '1105')
pool:
name: xxxxx
demands:
- vLAN -equals 1105
jobs:
- job: Common_1105
steps:
- template: Procedures/Common.yml
- job: Export_1105
dependsOn: Common_1105
steps:
- template: Procedures/Export.yml
parameters:
Server: OTS-01
And here is the "Procedures/Common.yml":
steps:
- checkout: git://xxxxx/yyyyy#$(Build.SourceBranchName)
clean: true
enabled: true
timeoutInMinutes: 1
- task: UsePythonVersion#0
enabled: true
timeoutInMinutes: 1
displayName: Select correct version of Python
inputs:
versionSpec: '3.8'
addToPath: true
architecture: 'x64'
- task: CmdLine#2
enabled: true
timeoutInMinutes: 5
displayName: Ensure Python Requirements Installed
inputs:
script: |
python -m pip install GitPython
And here is the "Procedures/Export.yml":
parameters:
- name: Server
type: string
steps:
- task: PythonScript#0
enabled: true
timeoutInMinutes: 3
displayName: xxxxx
inputs:
arguments: --name "xxxxx" --mode True --Server ${{ parameters.Server }}
scriptSource: 'filePath'
scriptPath: 'xxxxx/main.py'
I managed to make checkout work with variable branch names by using template expression variables ${{ ... }} instead of macro syntax $(...) variables.
The difference is that, template expressions are processed at compile time while macros are processed at runtime.
So in my case I have something like:
- checkout: git://xxx/yyy#${{ variables.BRANCH_NAME }}
For more information about variables syntax :
Understand variable syntax
I couldn't get it to work with expressions but I was able to get it to work using repository resources following the documentation at: https://learn.microsoft.com/en-us/azure/devops/pipelines/repos/multi-repo-checkout?view=azure-devops
resources:
repositories:
- repository: MyGitHubRepo # The name used to reference this repository in the checkout step
type: git
name: MyAzureProjectName/MyGitRepo
ref: $(Build.SourceBranch)
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
#some job
steps:
- checkout: MyGitHubRepo
#some other job
steps:
- checkout: MyGitHubRepo
- script: dir $(Build.SourcesDirectory)

How do you use an input variable to specify which self-hosted runner a GitHub action would run on?

I'm using GitHub Actions.
I'm trying to create a self-hosted runner that will run on one of several cloud servers, but be able to control which specific server it runs on. This is to do rolling updates on machines that have local resources.
I've setup tags with the self-hosted runners, but so far am having to make 1..N separate YML scripts:
on:
workflow_dispatch:
jobs:
post-to-server1:
runs-on: [self-hosted, server1 ]
Then I have to repeat this script n number of times.
What I'd like to do is this:
name: 'Server Patching'
on:
workflow_dispatch:
inputs:
server-target:
description: 'Target Server:'
required: true
default: 'dev'
jobs:
test-params:
runs-on: [ self-hosted, ${{ github.event.inputs.server-target }}]
steps:
- name: Start cloning of ${{ github.event.inputs.server-target }}
run: |
echo "Starting patching of: '${{ github.event.inputs.server-target }}'"
Check failure on line 12 in .github/workflows/test_workflow.yml
GitHub Actions / .github/workflows/test_workflow.yml
Invalid workflow file
You have an error in your yaml syntax on line 12
Is there a way to do this?
I tagged this YAML also, because the variable substitution seems to be an issue with the YAML syntax as well (although it may be specific for GitHub Actions)
Update: Yes, you can, if you change this line:
runs-on: [ self-hosted, ${{ github.event.inputs.server-target }}]
to:
runs-on: ${{ github.event.inputs.server-target }}
The error actually happens on test-params: not the line below it.
My theory is that the syntax checker fires before the variable substitution?
I'm not sure what makes difference, but it works for me:
runs-on: [ self-hosted, "${{ github.event.inputs.server-target }}" ]
Creating a list like that does not seem to work with dynamic values.
As long as you choose labels that are not already in use by GitHub (e.g. ubuntu-latest, macos-11, ...) you should not have a problem with dropping the self-hosted label. So your current naming pattern should be fine by itself
That way you can just use this:
runs-on: ${{ github.event.inputs.serverToPatch }}

Can you have multiple working directories with github actions?

So I have a repo with multiple directories for multiple go projects. Is there a way to run github actions on multiple working directories so I don't have to have redundant yaml with github actions? To automate an error check with golang, I currently have:
errcheck:
name: Errcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#master
- name: check
uses: grandcolline/golang-github-actions#v1.1.0
working-directory: ./app1
with:
run: errcheck
token: ${{ secrets.GITHUB_TOKEN }}
But I'd like to have:
errcheck:
name: Errcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#master
- name: check
uses: grandcolline/golang-github-actions#v1.1.0
working-directory: [./app1, ./app2]
with:
run: errcheck
token: ${{ secrets.GITHUB_TOKEN }}
In order to run something in more than one working directory, I believe you have two options:
Option 1: Matrix
Use GitHub Action's jobs.<job_id>.strategy.matrix option. This will create multiple jobs, each with its own matrix (directory) value.
Here is a sample workflow:
name: Test
on:
push: { branches: master }
jobs:
test:
name: Matrix test
runs-on: ubuntu-latest
strategy:
matrix: { dir: ['some-dir', 'other-dir'] }
steps:
- name: Checkout code
uses: actions/checkout#v2
- name: Do something with the matrix value
working-directory: ${{ matrix.dir }}
run: pwd
Running this will create two jobs:
Option 2: Custom Shell Script
If the matrix option is not suitable for your needs, a simple shell script that loops through and tests all your nested applications (directories) might be appropriate. In this case, you ignore the working-direcoty directive in the workflow YAML, and let the script cd to each of them.
For example:
#!/usr/bin/env bash
dirs=( some-dir other-dir )
for dir in "${dirs[#]}"; do
pushd "$dir"
pwd # Do something more significant here
popd
done

Fallback in expression syntax

I have a github workflow that runs on two different events: pull_request and manually. It looks like this:
on:
pull_request:
branches: [master]
workflow_dispatch: {}
env:
API_URL: https://example.com/
What I want is to be able to set an alternate API_URL when I trigger the workflow manually. But I want the workflow to run the same when it runs automatically.
So, first, I add “inputs” to the workflow_dispatch:
on:
pull_request:
branches: [master]
workflow_dispatch:
inputs:
API_URL:
description:
required: true
default: https://example.com
env:
API_URL: ${{ github.event.API_URL }}
From what I understand, this way the API_URL env variable will only be set when the workflow is run manually. But when it’s run automatically, there’s no github.event.API_URL value.
It seems to me that a conditional fallback here is needed.
Will something like this work?
env:
API_URL: ${{ github.event.API_URL || 'https://example.com/' }}
But from the docs the || operator will evaluate to 1 or 0.
Is there a good way to solve this? Thanks!
This worked for me:
env:
BRANCH: ${{ github.base_ref || 'devel' }}
Unfortunately (at the time of writing this), it's not possible that way. But you can achieve the same effect by setting the environment variable (API_URL) to the default value dynamically only when the job is not run manually (eg. the job is triggered by the PR event). You can do that by creating a conditional job step that will run only if API_URL has not been set yet:
on:
pull_request:
branches:
- master
workflow_dispatch:
inputs:
API_URL:
required: true
default: https://example.com
jobs:
build:
env:
API_URL: ${{ github.event.inputs.API_URL }}
runs-on: ubuntu-latest
steps:
- name: Set API_URL environment variable
if: env.API_URL == null
run: echo "API_URL=https://example.com" >> $GITHUB_ENV
- name: Test API_URL environment variable
run: echo "API_URL=$API_URL"
This way we will have API_URL environment variable set regardless of the way the workflow was triggered (either manually or automatically) with the ability to override it with a custom value when run manually.

Resources