I am trying to setup my first GitHub Workflow and I am facing many YAML syntax issues even I am using the official documentation.
I am using the below YAML:
# This is a basic workflow to help you get started with Actions
name: TestWorkflowGithub
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "main" branch
pull_request:
branches:
- 'testbranch/**'
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- name: Checkout the code
uses: actions/checkout#v3
- name: Install PMD
run: |
PMD_VERSION=`cat pmd/pmd-version.txt`
wget https://github.com/pmd/pmd/releases/download/pmd_releases%2F6.54.0/pmd-bin-6.54.0.zip
unzip pmd-bin-6.54.0.zip -d ~
mv ~/pmd-bin-$6.54.0 ~/pmd
~/pmd/bin/run.sh pmd --version
# Run PMD scandd
- name: Run PMD scan
run: ~/pmd/bin/run.sh pmd -d force-app -R pmd/ruleset.xml -f text
GitHub is showing me the below error:
You have an error in your yaml syntax on line 14
Note: the line 14 is "runs-on: ubuntu-latest"
Which is the syntax issue in the above YAML file?
You are missing the job identifier:
jobs:
foo: # <-- This
runs-on: ubuntu-latest
steps:
- name: Checkout the code
uses: actions/checkout#v3
steps:
You can use actionlint or vscode-yaml to avoid such syntax issues next time :)
Related
I'm trying to get this github action to work but once committed it gives me this error:
Invalid workflow file: .github/workflows/main.yml#L1
No steps defined in steps and no workflow called in uses for the following jobs: build
Anyone have any idea what this might depend on?
Below is the code I used:
name: Deploy to Cloud Foundry
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-18.04
# Build your app here
deploy:
runs-on: ubuntu-18.04
needs: build
steps:
- uses: citizen-of-planet-earth/cf-cli-action#master
with:
cf_api: https://api.my-cloud-foundry.com
cf_username: ${{ secrets.CF_USER }}
cf_password: ${{ secrets.CF_PASSWORD }}
cf_org: AwesomeApp
cf_space: Development
command: push -f manifest-dev.yml
Thanks in advance to everyone
Following the Workflow Syntax for Github Actions, you'll identify that some fields are mandatory.
At the workflow level, you need to have at least a trigger (configure with the on field) and a list of jobs specified.
Then, in that list of jobs, you have to specify at least one job, where each of those jobs needs at least the runner and the steps (or the uses for reusable workflow) field configured.
Example of the minimum configurations you would use for a job:
on: push
jobs:
job1:
runs-on: ubuntu-latest
steps:
- name: Print a greeting
run: echo 'Hello World'
job2: # reusable workflow scenario
uses: owner/repo/.github/workflows/reusable-workflow.yml#main
I couldn't make this workflow work, I'm always receiving this error every step must define a "uses" or "run" key, but looking at my script I don't see any issues, can someone pls help me fix this? It does not seem like a - problem as it usually is.
# This is a basic workflow to help you get started with Actions
name: Build Digital Ocean Image
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "master" branch
push:
branches:
- '*'
- '*/*'
- '**'
- '!master'
pull_request:
branches: [ "master" ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
packages:
runs-on: ubuntu-latest
steps:
- name: Install packages
run: |
apt-get install curl -y
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update && sudo apt-get install packer
apt-get install ansible -y
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
# runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout
uses: actions/checkout#v3
# Runs a single command using the runners shell
- name: Packer init
env:
DIGITALOCEAN_TOKEN=${{ secrets.DIGITALOCEAN_TOKEN }}
run: packer init
working-directory: /home/runner/work/packer-do-custom-images/demo
# Runs a set of commands using the runners shell
- name: Packer build
run: packer build .
working-directory: /home/runner/work/packer-do-custom-images/demo
The runs-on directive is missing (commented!), just add/uncomment it after the name, like:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
To fix the issue.
I would suggest to use the actionlint tool to discover error like this, as example:
> actionlint .github/workflows/test.yaml
.github/workflows/test.yaml:35:3: "runs-on" section is missing in job "build" [syntax-check]
|
35 | build:
| ^~~~~~
UPDATE:
As side notes also the env variable as issue: you should use : instead of = like:
- name: Packer init
env:
DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
I have a workflow in which a run request runs infinitely. i want to stop that run after 5 minutes of it running.
my workflow file:-
name: MSBuild
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
env:
# Path to the solution file relative to the root of the project.
SOLUTION_FILE_PATH: ./genshincheat.sln
# Configuration type to build.
# You can convert this to a build matrix if you need coverage of multiple configuration types.
# https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
BUILD_CONFIGURATION: Release
permissions:
contents: read
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout#v1
with:
submodules: recursive
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild#v1.0.2
- name: Restore NuGet packages
working-directory: ${{env.GITHUB_WORKSPACE}}
run: nuget restore ${{env.SOLUTION_FILE_PATH}}
- name: Build
working-directory: ${{env.GITHUB_WORKSPACE}}
# Add additional options to the MSBuild command line here (like platform or verbosity level).
# See https://learn.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}}
- uses: montudor/action-zip#v1
with:
args: zip -qq -r bin.zip dir
- uses: actions/checkout#v2
- run: mkdir -p path/to/artifact
- run: echo hello > path/to/artifact/world.txt
- uses: actions/upload-artifact#v3
with:
name: bin.zip
path: ./bin.zip
the "build" runs infinitely any way to stop it after 5 mins so it can carry out next jobs? it runs infinitely becauseafter build it runs the built program so i cant exit that ;-;. any help is appreciated
There are different fields that can help you achieve what you want.
At the job level: job.<id>.timeout-minutes (defining a job timeout)
At the step level: job.<id>.steps.timeout-minutes (defining a step timeout)
Which would look like this in your case:
At the job level:
build:
runs-on: windows-latest
timeout-minutes: 5
steps:
[...]
At the step which never ends (example):
- name: Build
timeout-minutes: 5
working-directory: ${{env.GITHUB_WORKSPACE}}
# Add additional options to the MSBuild command line here (like platform or verbosity level).
# See https://learn.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}}
Another reference on the Github Community
I have this workflow in a repo called terraform-do-database and I'm trying to use a reusable workflow coming from the public repo foo/git-workflows/.github/workflows/tag_validation.yaml#master
name: Tag Validation
on:
pull_request:
branches: [master]
push:
branches:
- '*' # matches every branch that doesn't contain a '/'
- '*/*' # matches every branch containing a single '/'
- '**' # matches every branch
- '!master' # excludes master
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
tag_check:
uses: foo/git-workflows/.github/workflows/tag_validation.yaml#master
And this is the reusable workflow file from the public git-workflows repo that has the script that should run on it. What is happening is that the workflow is trying to use a script inside the repo terraform-do-database
name: Tag Validation
on:
pull_request:
branches: [master]
workflow_call:
jobs:
tag_check:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout#v3
# Runs a single command using the runners shell
- name: Verify the tag value
run: ./scripts/tag_verify.sh
So the question: How can I make the workflow use the script stored in the git-worflows repo instead of the terraform-do-database?
I want to have a single repo where I can call the workflow and the scripts, I don't want to have everything duplicated inside all my repos.
I have found that if I wrap the script into a composite action. I can use GitHub context github.action_path to locate the scripts.
Example:
run: ${{ github.action_path }}/scripts/foo.sh
One way to go about this is perform a checkout inside your reusable workflow that essentially clones the content of the repo where your scripts are and only then you can access it. It's not the cleanest solution but it works.
Perform a second checkout, to clone your repo that has the reusable workflow into a dir reusable-workflow-repo
- name: Checkout reusable workflow dir
uses: actions/checkout#v3
with:
repository: <your-org>/terraform-do-database
token: ${{ secrets.GIT_ACCESS_TOKEN }}
path: reusable-workflow-repo
Now you have all the code you need inside reusable-workflow-repo. Use ${GITHUB_WORKSPACE} to find the current path and simply append the path to the script.
- name: Verify the tag value
run: ${GITHUB_WORKSPACE}/reusable-workflow-repo/scripts/tag_verify.sh
I was able to solve it adding a few more commands to manually download the script and execute it.
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout#v3
# Runs a single command using the runners shell
- name: Check current directory
run: pwd
- name: Download the script
run: curl -o $PWD/tag_verify.sh https://raw.githubusercontent.com/foo/git-workflows/master/scripts/tag_verify.sh
- name: Give script permissions
run: chmod +x $PWD/tag_verify.sh
- name: Execute script
run: $PWD/tag_verify.sh
Following Kaleby Cadorin example but for the case where the script is in a private repository
- name: Download & run script
run: |
curl --header "Authorization: token ${{ secrets.MY_PAT }}" \
--header 'Accept: application/vnd.github.raw' \
--remote-name \
--location https://raw.githubusercontent.com/COMPANY/REPO/BRANCH/PATH/script.sh
chmod +x script.sh
./script.sh
Note: GITHUB_TOKEN doesn't seem to work here, a PAT is required.
According to this thread on github-community the script needs to be downloaded/checked out separatly.
The "reusable" workflow you posted is not reusable in this sense, because since it is not downloading the script the workflow can only run within its own repository (or a repository that already has the script).
I am trying to create a bug tracker that allows me to record the error messages of the python script I run. Here is my YAML file at the moment:
name: Bug Tracker
#Controls when the workflow will run
on:
# Triggers the workflow on push request events
push:
branches: [ main ]
# Allows you to run this workflow manually from the Actions tab (for testing)
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:
# Self Hosted Runner
runs-on: windows-latest
# Steps for tracker to get activated
steps:
# Checks-out your repository under BugTracker so the job can find it
- uses: actions/checkout#v2
- name: setup python
uses: actions/setup-python#v2
with:
python-version: 3.8
# Runs main script to look for
- name: Run File and collect bug
id: response
run: |
echo Running File...
python script.py
echo "${{steps.response.outputs.result}}"
Every time I run the workflow I can't save the error code. By save the error code, I mean for example... if the python script produces "Process completed with exit code 1." then I can save that to a txt file. I've seen cases where I could save if it runs successfully. I've thought about getting the error in the python script but I don't want to have to add the same code to every file if I don't have to. Any thoughts? Greatly appreciate any help or suggestions.
Update: I have been able to successfully use code in python to save to the txt file. However, I'm still looking to do this in Github if anyone has any suggestions.
You could :
redirect the output to a log file while capturing the exit code
set an output with the exit code value like:
echo ::set-output name=status::$status
in another step, commit the log file
in a final step, check that the exit code is success (0) otherwise exit the script with this exit code
Using ubuntu-latest, it would be like this:
name: Bug Tracker
on: [push,workflow_dispatch]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: setup python
uses: actions/setup-python#v2
with:
python-version: 3.8
- name: Run File and collect logs
id: run
run: |
echo Running File...
status=$(python script.py > log.txt 2>&1; echo $?)
cat log.txt
echo ::set-output name=status::$status
- name: Commit log
run: |
git config --global user.name 'GitHub Action'
git config --global user.email 'action#github.com'
git add -A
git checkout master
git diff-index --quiet HEAD || git commit -am "deploy workflow logs"
git push
- name: Check run status
if: steps.run.outputs.status != '0'
run: exit "${{ steps.run.outputs.status }}"
On windows, I think you would need to update this part:
status=$(python script.py > log.txt 2>&1; echo $?)
cat log.txt