How to run a Ruby script on a Github Workflow - ruby

I have a Ruby script that I want to run when a pull-request is created. This pull-request validates a series of conditions to be sure the pull-request can be merged. It's a very simple script with no external gems, just standard Ruby.
I'm trying to run this script on a job on a run step. The problem is, I'm not sure the path where the file should be saved.
The script is called: validator.rb. From my local computer I can run the script using:
ruby -r ./validator.rb -e "Validator.new.validate_something 'One parameter'"
This works fine locally but when I push this to GitHub it is failing. I saved my script as .github/workflows/ruby-scripts so my job looks like this:
jobs:
title:
name: "Title"
runs-on: ubuntu-latest
steps:
- run: ruby -r ./ruby-scripts/validator.rb -e "Validator.new.validate_something '${{ github.event.pull_request.title}}'"
And I get:
Run ruby -r ./ruby-scripts/validator.rb -e "Validator.new.validate 'Create README.md'"
/usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb:10: warning: constant Gem::ConfigMap is deprecated
/usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb:10: warning: constant Gem::ConfigMap is deprecated
/usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb:29: warning: constant Gem::ConfigMap is deprecated
/usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb:30: warning: constant Gem::ConfigMap is deprecated
/usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb:10: warning: constant Gem::ConfigMap is deprecated
/usr/local/lib/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:92:in `require': cannot load such file -- ./ruby-scripts/validator.rb (LoadError)
from /usr/local/lib/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:92:in `require'
##[error]Process completed with exit code 1.
I tried with all the possible combination of paths and it fails each time.
Running pwd and ls returned:
- run: pwd => /home/runner/work/repo-name/repo-name
- run: ls => shell: /bin/bash -e {0}
What is the right way to do this?

As I've mentioned in the comments, the reason why your workflow isn't working is that you forgot the crucial step that checks-out your repository. By default, the workspace is empty unless you check out the repository with the Checkout GitHub Action.
From the GitHub Action's README:
This action checks-out your repository under $GITHUB_WORKSPACE, so your workflow can access it.
Here's an example:
- name: Checkout Repo
uses: actions/checkout#v2
(That's it, really)
(Note: You don't have to specify a name for the step.)

For me, the problem was also the location of the file. The ruby script was running in the root of the repository, not in the same path as the workflow YAML (as I was expecting).
I was running run: ruby -r ./my-file.rb, where my-file.rb was next to the workflow yaml.
I realized this by adding this step:
- run: ruby -e 'p `ls`.split("\n")'
Which printed the output of ls in a ruby array.
I fixed using:
run: ruby ./.github/workflows/my_file.rb

Related

Gitlab CI: Stage variable based on global variable is not resolved when using anchors

I have something like this in my .gitlab-ci.yml file:
.docker_build_cmd: &docker_build_cmd >-
docker build -t $DOCKER_IMAGE_TAG -f $DOCKER_FILE .
variables:
PROJECT_NAME: best-app-ever
BUILD_VERSION: 4.2.0
DOCKER_IMAGE_TAG: $DOCKER_PROJECT_NAME:$BUILD_VERSION
build:
stage: build
variables:
GRADLE_CMD: app:build
DOCKER_PROJECT_NAME: $PROJECT_NAME-service
DOCKER_FILE: docker/service.dockerfile
script:
- echo $DOCKER_PROJECT_NAME
- echo $DOCKER_IMAGE_TAG
- *docker_build_cmd
but runner says:
$ echo $DOCKER_PROJECT_NAME
best-app-ever
$ echo $DOCKER_IMAGE_TAG
$PROJECT_NAME-service:4.2.0
$ docker build -t $DOCKER_IMAGE_TAG -f $DOCKER_FILE .
invalid argument "$PROJECT_NAME-service:4.2.0" for "-t, --tag" flag: invalid reference format: repository name must be lowercase
Does anyone understand why it happens?
How Gitlab processes the .yml?
And if there is a way to make it work as I intended, I am really want to know.
GitLab SaaS version is 14.3.0-ee.
UPD. After some googling it seems that "variable_inside_variable" feature flag has to be enabled. Will do it tomorrow and see what changes.
GitLab CI "variable inside variable" feature was disabled, so I asked admins to toggle it and everything became fine. Don't think that this could be helpful question for many, because GitLab already enabled the feature globally, but if you have a standalone solution and the same issue, then you know what to do.

Having Gitlab Projects calling the same gitlab-ci.yml stored in a central location

I have many Gitlab project followed the same CI template. Whenever there is a small change in the CI script, I have to manually modify the CI script in each project. Is there a way you can store your CI script in a central location and have your project called that CI script with some environment variable substitution? For instance,
gitlab-ci.yml in each project
/bin/bash -c "$(curl -fsSL <link_to_the_central_location>.sh)"
gitlab-ci.yml in the central location
stages:
- build
- test
build-code-job:
stage: build
script:
- echo "Check the ruby version, then build some Ruby project files:"
- ruby -v
- rake
test-code-job1:
stage: test
script:
- echo "If the files are built successfully, test some files with one command:"
- rake test1
test-code-job2:
stage: test
script:
- echo "If the files are built successfully, test other files with a different command:"
- rake test2
You do not need curl, actually gitlab supports this via the include directive.
you need a repository, where you store your general yml files. (you can choose if it is a whole ci file, or just parts. For this example lets call this repository CI and assume your gitlab runs at example.com - so the project url would be example.com/ci. we create two files in there just to show the possibilities.
is a whole CI definition, ready to use - lets call the file ci.yml. This approach is not really flexible
stages:
- build
- test
build-code-job:
stage: build
script:
- echo "Check the ruby version, then build some Ruby project files:"
- ruby -v
- rake
test-code-job1:
stage: test
script:
- echo "If the files are built successfully, test some files with one command:"
- rake test1
test-code-job2:
stage: test
script:
- echo "If the files are built successfully, test other files with a different command:"
- rake test2
is a partly CI definition, which is more extendable. lets call the files includes.yml
.build:
stage: build
script:
- echo "Check the ruby version, then build some Ruby project files:"
- ruby -v
- rake
.test:
stage: test
script:
- echo "this script tag will be overwritten"
There is even the option to use template string from yaml. please reference the gitlab documentation but it is similar to 2.
we do have our project which wants to use such definitions. so either
For the whole CI file
include:
- project: 'ci'
ref: master # think about tagging if you need it
file: 'ci.yml'
as you can see now we are referencing one yml file, with all the cahnges.
with partial extends
include:
- project: 'ci'
ref: master # think about tagging if you need it
file: 'includes.yml'
stages:
- build
- test
build-code-job:
extends: .build
job1:
extends: .test
script:
- rake test1
job2:
extends: .test
script:
- rake test2
As you see, you can easily use the includes, to have a way more granular setup. Additionally you could define at job1 and job2 variables, eg for the test target, and move the script block into the includes.yml
Futhermore you can also use anchors for the script parts. Which looks like this
includes.yml
.build-scirpt: &build
- echo "Check the ruby version, then build some Ruby project files:"
- ruby -v
- rake
.build:
stage: build
script:
- *build
and you can use also the script anchor within your configuration
For a deeper explanation you can also take a look at https://docs.gitlab.com/ee/ci/yaml/includes.html

How can we use environment variables in a Jekyll config file?

Is there a way I can use one my bash environment variable (say $FOO) in my Jekyll's _config.yml file?
I've tried using:
foo = <%= ENV['FOO'] %>
But it didn't work as the Ruby code wasn't interpreted.
Versions used:
Ruby: 2.1.2
Jekyll: 2.5.3
If your goal is to use environment variables as liquid items {{ site.something }}, you might be able to get this thing in your Gemfile a go:
gem 'jekyll-environment-variables', group: :jekyll_plugins
And then you'll be able to use {{ site.env.HOME }} and expect it be converted to something like /home/ubuntu in the output HTML.
Disclosure: I am the owner of the gem and I've been using it personally since long ago.
The answer by #elryco is close but not quite right, at least for my setup. It took some trial and error, but this finally worked. Note this only works for certain env vars supported by the contentful plugin.
Note that you need the gem jekyll-contentful-data-import (v1.7.0 or up) for this solution to actually work.
Bash environment (e.g., ~/.bash_profile):
export CONTENTFUL_ACCESS_TOKEN=foo
export CONTENTFUL_SPACE_ID=bar
In _config.yml, reference them as:
contentful:
spaces:
- example:
space: ENV_CONTENTFUL_SPACE_ID
access_token: ENV_CONTENTFUL_ACCESS_TOKEN
This is the same as what's written in the Github documentation.
I recently had to try and do this myself. It turns out you can't put environment variables directly into a Jekyll config file, but you can write a rake task that will take environment variables and apply them to your config.
Here's an example:
# Rakefile
require 'jekyll'
task default: %w[build]
desc "Build the site"
task :build do
config = Jekyll.configuration({
url: ENV["SITE_URL"],
})
site = Jekyll::Site.new(config)
Jekyll::Commands::Build.build(site, config)
end
Unfortunately there is no direct way of accessing it in liquid tags, At Least not officially.
But I wrote a wrapper script which reads environment variables before jekyll starts and appends it to _config.yml file and deletes the variable post build.
echo "secret-variable: $PASSWORD" >> _config.yml
bundle exec jekyll build -d target
sed '$d' _config.yml //this is to delete the last line
Now I'm free to use site.secret-variable anywhere in the liquid tags.
I know that this not the right way of doing it, But so is writing a custom ruby script.
I personally find the use of a ruby Jekyll plugin more appropriate and portable. There's a very simple yet effective solution available here.
The main idea is ruby will have access to the ENV variables so you can use a small ruby plugin to load into your site.config liquid array all the information you want from the environment. And you can define default values as well.
Please note that the example given in the link isn't the most relevant since the prod/staging environment is already offered by Jekyll natively with the build command options.
It is now possible to use bash environment variable (say $FOO) in Jekyll's _config.yml file with GitHub Actions:
# _config.yml
title: FOO
Create a bash script say sample.sh to replace for a given input string FOO and replace with another string
# github/workflows/sample.sh
export FOO=XYZ
while IFS='' read -r a; do
echo "${a//FOO/$FOO}"
done < /_config.yml > /_config.yml.t
mv /_config.yml{.t,}
Create a workflow file, say github-pages.yml, put the script before Build with Jekyll:
# Sample workflow for building and deploying a Jekyll site to GitHub Pages
name: Deploy Jekyll with GitHub Pages dependencies preinstalled
on:
# Runs on pushes targeting the default branch
push:
branches:
- 'master'
- 'mybranch'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout#v3
- name: Setup Pages
uses: actions/configure-pages#v2
- name: Utilize FOO
run: |
bash .github/workflows/sample.sh
- name: Build with Jekyll
uses: actions/jekyll-build-pages#v1
with:
source: ./
destination: ./_site
- name: Upload artifact
uses: actions/upload-pages-artifact#v1
# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages#v1
If your bash environment variables are declared like this
export ENV_ACCESS_TOKEN=xxxxx
export ENV_SPACE_ID=yyyyyy
You can get it like this in your config.yml
space: ENV_SPACE_ID # Required
access_token: ENV_ACCESS_TOKEN # Required

Travis build with nodejs en custom ftp

I m trying to use travis CI with nodejs and I m facing a problem like this one.
What I want here, is only to use ftp to upload my file, not to run any command.
No Rakefile found (looking for: rakefile, Rakefile, rakefile.rb, Rakefile.rb)
I dont know what is the problem actually... Here's my travis.yml file :
env:
global:
- "FTP_USER=xxx"
- "FTP_PASSWORD=xxx"
after_success:
"curl --ftp-create-dirs -T uploadfilename -u $FTP_USER:$FTP_PASSWORD ftp://xxxx.fr/www/mochatest"
What am I doing wrong ?
I faced similar scenario when I decided to use Travis-CI with HTML+JS app. I finally ended up deployment from my package.json file via "posttest" section. I wrote some code which uses ftp-deploy npm module to upload the files. Test repository here.

Can't make Travis-CI work

I'm trying to set up Travis on this repo: https://github.com/lcguida/worksheet
I've put the travis.yml file there.
I've enabled the repository in my travis account (the "ON" button)
I've pushed some commits to see if it woukld trigger the tester.
I'm always getting this message in "My Repositories" tab: You don't have any repos set up on Travis CI
Here is my travis.yml file:
language: ruby
rvm:
- 2.0.0
- 2.1.1
script: 'bundle exec rake test'
Can't figure out what I'm doing wrrong
I made the same mistake as you when starting on Travis :-)
The file name you need is .travis.yml
Note the first dot.
You can see what's wrong by looking at https://travis-ci.org/lcguida/worksheet/requests . . . where it repeatedly says "missing config"

Resources