According to the documentation of capistrano, I can get user input with the ask() method. I created the following task:
desc "Ask for user input"
task :ask_for_user_input do
ask ':update_assets', 'Update assets (y/n, default=n)?', 'n'
end
and in deploy.rb I have
namespace :deploy do
...
before :deploy, "deploy:ask_for_user_input"
...
end
But no matter what, capistrano never asks for user input. I tried different variations (e.g. putting the "ask" method directly in deploy.rb or my stage files but it did not change anything. What am I missing here?
I prompt for user input in my staging file. Perhaps it's your syntax? The ask() method can be used like this:
# ask for user input
ask(:update_assets, 'Update assets (y/n, default=n)', 'n', echo: true)
# get the user input
fetch(:update_assets)
Sources: Capistrano User Input, How can I get Capistrano to prompt for a password?
Related
I am using Azure Devops Release pipeline to automatically publish Pull Requests to test domain branchname.blablabla.com
Everything works fine, but sometimes branch name contains dot . and deployment task fails due to 4th level domain name like branch.name.blablabla.com
Is there a way to remove illegal characters from $(Build.SourceBranchName) before it binds to PARAMETERS_WEBSITENAME?
You can add one additional task before using it in website name, to remove dot from the branch name. For example, you can add Bash task to run one shell script:
a="$(echo $(Build.SourceBranchName) | tr -d .)"
echo "##vso[task.setvariable variable=BranchName]$a"
In this script, it firstly remove dot . from $(Build.SourceBranchName) value. Then create one new variable BranchName and assign the modified value to it.
Now, in your next task, you can call this modified value by using $(BranchName).
I started writing a little tool that basically can do something (ex. compile or test code) and then send an email if it fails.
https://github.com/JohnReedLOL/EmailTestingBot
I want to add a feature where this tool can programmatically look at the last commit in the working directory, look at the author of the commit, extract their email, and then email that person whether their commit resulted in a pass or a failure.
For example, I want it to do something like: Git: See my last commit
Where the email basically says:
Subject: Test Results
Message: All your tests passed in dev for commit 0e39756383662573.
Does Jenkins provide this functionality already? I want to make my setup email the person who put in the most recent commit.
Also, is there a way I can obtain the email of the author of the most recent commit programmatically (ex. perhaps with http://www.eclipse.org/jgit/ or http://javagit.sourceforge.net )?
I don't really care how I get email notifications - I just want them and I can't use TravisCI.
I will try to give solutions part by part.
Part 1 :
Yes, you can run ShellScript(Shell Commands) from Jenkins Link.
Part 2
How to get the Email Id and other Stuff from GitCommit.
For that Jenkins sever should have git command installed in build server.
Create one conf file ex. /conf/reference which have
app {
git {
commit = "CURRENT_COMMIT"
repo = "CURRENT_REPO"
timestamp = "CURRENT_TIMESTAMP"
emailId = "EMAIL_ID"
}
}
When making your build run the command
sed -i'' "s/CURRENT_COMMIT/$(git rev-parse HEAD)/g" conf/reference.conf
sed -i'' "s^CURRENT_REPO^$(git config --get remote.origin.url)^g" conf/reference.conf
sed -i'' "s/CURRENT_TIMESTAMP/$(git show -s --format=%ci HEAD)/g" conf/reference.conf
sed -i'' "s/EMAIL_ID/git --no-pager show -s --format='%an <%ae>' CURRENT_COMMIT/g" conf/reference.conf
above code will put the values in reference.conf.
Now you can use to get the info and send the mail. As far as I know, Jenkins gives the capability to send the Email. Jenkins work on the environment variables rather than putting this into reference.conf you can put this in Environment variable and use the environment variables to send the mail.
FYI: I haven't tested this code but as far as I remember working in Jenkins, we used to send email through this way.
#HappyCoding
I am using team city with git. I am trying to take different action on the basis of the branch name from build is getting triggered. Build gets triggered from a branch in which a change gets checked in.
I have branch name like US12345, F12345, DE12345 and I want to perform different tests on these different builds.
For this I have added a command line step and try to run a custom script (Windwos batch script). Here is the script:
#ECHO OFF
echo "BRANCH Name: %teamcity.build.branch%"
SET BranchName="%teamcity.build.branch%"
if /I %%BranchName:~0,1%%==F (echo Working on a feature branch && <take action 1>)
if /I %%BranchName:~0,2%%==US (echo Working on a story branch && <take action 2>)
if /I %%BranchName:~0,2%%==DE (echo Working on a defect branch && <take action 3>)
if /I %%BranchName:~0,2%%==QA (echo Working on a QA1 branch && <take action 4>)
In the above script, first I am assigning value of current branch name to a varialbe "BranchName".
Then in the first if condition, I am taking out first character of that variable and check if that character is equal to F. If that is true then I want to perform some set to tasks.
In the second if condition, I am taking out first two characters of "BranchName" and check if it is equal to US? If it is then I perform another different set of actions.
In the same way I want to do in third and fourth if condition.
Now the problem is, I am not able to get first few characters of a variable in the custom script because teamcity treats everything inside a "%%" as a reference parameter and we have to add those parameters in the build configuration.
Has anyone worked in these use case? Any help would be greatly appreciated.
If you want to pass % to TeamCity, you should escape it with other %, i.e. for % it must be %%, for %% it must be %%%%
You are cramming all your different branch builds into a single configuration, then using a bat file to trigger what gets build...that sounds complicated, and also a good choice for VSC trigger in TeamCity. I can a suited approach:
Create one build configuration, then create a VCS trigger for your desired branch name to trigger the build.
Copy that configuration N-times, one for each branch you want to build, then reconfigure the VSC trigger to have the correct branch name.
If you want to keep doing what you are doing, use PoSh instead of BAT script. Add a PowerShell step, change the script to be "Source Code" and enter this under "Script source":
$branch = "%teamcity.build.branch%"
if ($branch.StartsWith('F')) {
echo "Working on a feature branch $branch"
}
elseif ($branch.StartsWith('US')) {
echo "Working on a feature branch $branch"
}
elseif ($branch.StartsWith('DE')) {
echo "Working on a feature branch $branch"
}
elseif ($branch.StartsWith('QA')) {
echo "Working on a feature branch $branch"
}
I'm looking into the possibility of using Capistrano as a generic deploy solution. By "generic", I mean not-rails. I'm not happy with the quality of the documentation I'm finding, though, granted, I'm not looking at the ones that presume you are deploying rails. So I'll just try to hack up something based on a few examples, but there are a couple of problems I'm facing right from the start.
My problem is that cap deploy doesn't have enough information to do anything. Importantly, it is missing the tag for the version I want to deploy, and this has to be passed on the command line.
The other problem is how I specify my git repository. Our git server is accessed by SSH on the user's account, but I don't know how to change deploy.rb to use the user's id as part of the scm URL.
So, how do I accomplish these things?
Example
I want to deploy the result of the first sprint of the second release. That's tagged in the git repository as r2s1. Also, let's say user "johndoe" gets the task of deploying the system. To access the repository, he has to use the URL johndoe#gitsrv.domain:app. So the remote URL for the repository depends on the user id.
The command lines to get the desired files would be these:
git clone johndoe#gitsrv.domain:app
cd app
git checkout r2s1
Update: For Capistrano 3, see scieslak's answer below.
Has jarrad has said, capistrano-ash is a good basic set of helper modules to deploy other project types, though it's not required as at the end of the day. It's just a scripting language and most tasks are done with the system commands and end up becoming almost shell script like.
To pass in parameters, you can set the -s flag when running cap to give you a key value pair. First create a task like this.
desc "Parameter Testing"
task :parameter do
puts "Parameter test #{branch} #{tag}"
end
Then start your task like so.
cap test:parameter -s branch=master -s tag=1.0.0
For the last part. I would recommend setting up passwordless access using ssh keys to your server. But if you want to take it from the current logged in user. You can do something like this.
desc "Parameter Testing"
task :parameter do
system("whoami", user)
puts "Parameter test #{user} #{branch} #{tag}"
end
UPDATE: Edited to work with the latest versions of Capistrano. The configuration array is no longer available.
Global Parameters: See comments Use set :branch, fetch(:branch, 'a-default-value') to use parameters globally. (And pass them with -S instead.)
Update. Regarding passing parameters to Capistrano 3 task only.
I know this question is quite old but still pops up first on Google when searching for passing parameters to Capistrano task. Unfortunately, the fantastic answer provided by Jamie Sutherland is no longer valid with Capistrano 3. Before you waste your time trying it out except the results to be like below:
cap test:parameter -s branch=master
outputs :
cap aborted!
OptionParser::AmbiguousOption: ambiguous option: -s
OptionParser::InvalidOption: invalid option: s
and
cap test:parameter -S branch=master
outputs:
invalid option: -S
The valid answers for Capistrano 3 provided by #senz and Brad Dwyer you can find by clicking this gold link:
Capistrano 3 pulling command line arguments
For completeness see the code below to find out about two option you have.
1st option:
You can iterate tasks with the key and value as you do with regular hashes:
desc "This task accepts optional parameters"
task :task_with_params, :first_param, :second_param do |task_name, parameter|
run_locally do
puts "Task name: #{task_name}"
puts "First parameter: #{parameter[:first_param]}"
puts "Second parameter: #{parameter[:second_param]}"
end
end
Make sure there is no space between parameters when you call cap:
cap production task_with_params[one,two]
2nd option:
While you call any task, you can assign environmental variables and then call them from the code:
set :first_param, ENV['first_env'] || 'first default'
set :second_param, ENV['second_env'] || 'second default'
desc "This task accepts optional parameters"
task :task_with_env_params do
run_locally do
puts "First parameter: #{fetch(:first_param)}"
puts "Second parameter: #{fetch(:second_param)}"
end
end
To assign environmental variables, call cap like bellow:
cap production task_with_env_params first_env=one second_env=two
Hope that will save you some time.
I'd suggest to use ENV variables.
Somethings like this (command):
$ GIT_REPO="johndoe#gitsrv.domain:app" GIT_BRANCH="r2s1" cap testing
Cap config:
#deploy.rb:
task :testing, :roles => :app do
puts ENV['GIT_REPO']
puts ENV['GIT_BRANCH']
end
And take a look at the https://github.com/capistrano/capistrano/wiki/2.x-Multistage-Extension, may be this approach will be useful for you as well.
As Jamie already showed, you can pass parameters to tasks with the -s flag. I want to show you how you additionally can use a default value.
If you want to work with default values, you have to use fetch instead of ||= or checking for nil:
namespace :logs do
task :tail do
file = fetch(:file, 'production') # sets 'production' as default value
puts "I would use #{file}.log now"
end
end
You can either run this task by (uses the default value production for file)
$ cap logs:tail
or (uses the value cron for file
$ cap logs:tail -s file=cron
Check out capistrano-ash for a library that helps with non-rails deployment. I use it to deploy a PyroCMS app and it works great.
Here is a snippet from my Capfile for that project:
# deploy from git repo
set :repository, "git#git.mygitserver.com:mygitrepo.git"
# tells cap to use git
set :scm, :git
I'm not sure I understand the last two parts of the question. Provide some more detail and I'd be happy to help.
EDIT after example given:
set :repository, "#{scm_user}#gitsrv.domain:app"
Then each person with deploy priveledges can add the following to their local ~/.caprc file:
set :scm_user, 'someuser'
We have a CVS repository and we create a tag on the active branch whenever a successful build is done.
Is there any way by which I can determine the date when the tag was created?
Looking into the history doesn't helps since it only tells the date-time stamps of the file when it was modified.
Thanks!
You can easily configure CVS to log all tag-related actions.
In the file '$CVSROOT/CVSROOT/taginfo' you can hook up a
pre-tag script like this:
ALL $CVSROOT/CVSROOT/do_tag
If this script returns a non-zero exit value, the tag operation will
be aborted. This allows for syntax checks on the tag names. You can
also use this hook to send emails, whenever a new release has been
tagged. To write a history of all tag operations, you need to do
something like this in your do_tag file:
#!/bin/sh
TAGHISTORY=~cvs/taghistory.log
echo -n "$(date): user $USER, tag " >> $TAGHISTORY
echo "$*" >> $TAGHISTORY
exit 0
If you have the history function enabled, you can execute
the following command:
cvs history -a -T
It will give you some lines like this, giving you date+time, user, module and tagname of each tagging operation:
T 2011-04-02 07:55 +0000 ralph mylib [testtag:A]
For more information check the cvsbook on history