VSTS / TFS Build only run NPM task when Git tag is committed and pushed - node.js

On Microsoft docs it states you can set conditionals for a specific build task. For example to run the build on a specific version of a defined Git branch.
But is it also possible to make an conditional to make the VSTS to build the NPM package only if a commit contains a git-tag?
Update 1: The command $ git describe (source) seems like a possible part of the solution. This command takes the last commit hash and matches it to see if there were annotated tags. However, it doesn't equal it to a boolean value what we need in the custom condition of VSTS.
Update 2: Using npm git-describe you can return wether or not the latest commit has annotated tags. Example of a gulp task:
/** Example of a gulp task using git describe */
var gulp = require('gulp');
var {gitDescribeSync} = require('git-describe');
/**
* #function
* #name checkGitTag
* #description Returns wether or not the latest commit has a tag
* #returns {(String|null)} Git tag or null if no git tag exists on the commit
*/
var checkGitTag = function() {
var gitInfo = gitDescribeSync();
// output the result to debug
console.log(gitInfo.tag);
// gitInfo.tag seems to contain the logic needed
};
gulp.task('checkGitTag', checkGitTag);
module.exports = checkGitTag;
Maybe by installing the NPM package on the build server and using a similar function would work. Going to test it out.

Yes, it’s possible to conditional run a task when the build commit contains tag(s).
But since there is no such predefined variable to record the tag for the build commit $(BUILD.SOURCEVERSION), so you should add the steps (add a variable and a PowerShell task) to check if there has tag(s) on the build commit. Detail step as below:
1. Add a variable (such as result) with the default value 0. And the variable is used for check if the build commit contains tag(s).
2. Then add a PowerShell task before the task which you want to conditional run, and the powershell script as below:
$tag=$(git tag --contains $(BUILD.SOURCEVERSION))
if($tag)
{
Write-Host "##vso[task.setvariable variable=result]1"
echo "The build version $(BUILD.SOURCEVERSION) contains tag(s)"
}
else
{
Write-Host "##vso[task.setvariable variable=result]0"
echo "The build version $(BUILD.SOURCEVERSION) does not contain any tags"
}
3. Finally set custom condition for the task you want to run only when the commit contains tag as below:
and(succeeded(), eq(variables['result'], '1'))

Related

Gitlab CI/CD cannot git push from .gitlab-ci.yml

I'm writing GitLab CI/CD pipeline script in .gitlab-ci.yml
I want to check if a specific file changed in another repo and if so I would like to copy the file, commit and push to the current repo.
everything works until I get to the 'git push' part
I tried several ways to fixed it:
stages:
- build
build:
stage: build
script:
- echo "Building"
- git checkout -b try
- git remote add -f b https://gitlab-ci-token:${CI_JOB_TOKEN}#gitlab.{otherRepo}.git
- git remote update
- CHANGED=$(git diff try:mobile_map.conf b/master:mobile_map.conf)
- if [ -n "${CHANGED}" ]; then
echo 'changed';
FILE=$(git show b/master:mobile_map.conf > mobile_map.conf);
git add mobile_map.conf;
git commit -m "updating conf file";
git push;
else
echo 'not changed';
fi
- git remote rm b
for this code I get :
fatal: unable to access 'https://gitlab-ci-token:[MASKED]#gitlab.{curr_repo}.git/': The requested URL returned error: 403
also I tried to add this line in the beginning :
git remote set-url origin 'https://{MY_USER_NAME}:"\"${PASSWORD}\""#gitlab.{curr_repo}.git'
and I get this error message:
fatal: Authentication failed for 'https://{MY_USER_NAME}:"\"${PASSWORD}\""#{curr_repo}.git/'
also I added:
- git config --global user.name {MY_USER_NAME}
- git config --global user.email {MY_EMAIL}
please help me,
Thanks
Job-tokens only have read-permission to your repository.
A unique job token is generated for each job and provides the user read access all projects that would be normally accessible to the user creating that job. The unique job token does not have any write permissions, but there is a proposal to add support.
You can't use deploy-tokens because they can't have write-access to a repository (possible tokens).
You could use a project-access-token with read-write-access to your repository.
You can use project access tokens:
On GitLab SaaS if you have the Premium license tier or higher. Project
access tokens are not available with a trial license.
On self-managed instances of GitLab, with any license tier. If you
have the Free tier: [...]
Then you can use your project-access-token as an environment variable in the url.
git push "https://gitlab-ci-token:$PROJECT_ACCESS_TOKEN#$CI_SERVER_HOST/$CI_PROJECT_PATH.git"
At least that's how we use it in our pipelines.
I hope this helps you further.
Complete example of simple GitLab CI stage, that commits back to its own repo
ci_section_name:
# N.B. This stage produces an extra commit to the repo!
stage: stage_name
script:
- apt-get update && apt-get install -y git
- echo "hello" >> file_to_be_modified.txt # your real job may do smth else
after_script:
- git config user.name "Name On Your Choice"
- git config user.email "email_on_your_choice#$CI_SERVER_HOST"
- git pull "https://project_access_token_name:$PROJECT_VARIABLE_WITH_ACCESS_TOKEN_VALUE#$CI_SERVER_HOST/$CI_PROJECT_PATH.git" $CI_COMMIT_BRANCH --rebase --autostash
- git commit -a -m "Message on your choice"
- git push "https://project_access_token_name:$PROJECT_VARIABLE_WITH_ACCESS_TOKEN_VALUE#$CI_SERVER_HOST/$CI_PROJECT_PATH.git" HEAD:$CI_COMMIT_BRANCH
I want to stop on few important aspects:
file_to_be_modified.txt - any modified files in the example are supposed to already exist in the repo, if you need add smth new, you will need
include at least git add command
project_access_token_name - is the name of used Project Access Token, not the token value itself (see screenshots below); you should create it by hands for your GitLab project if necessary
PROJECT_VARIABLE_WITH_ACCESS_TOKEN_VALUE - is the name of Project Variable (see screenshots below), you should create this variable by hands for your GitLab project and populate it with value of chosen Project Access Token; btw, you can add literal value of the token into stage code instead, but it is probably bad for security reasons
--rebase --autostash - note that autostashing your changes instead of simply trying to pull-push them will help you to guarantee the push in case of conflicts (even our new GitLab stage may conflict between its launches) but files would be left with conflict trace instead of correct content; because it is hard to resolve conflicts automatically, it is supposed that you control such situation with another tools (for example, further build on conflict state will simply fail)
This simple example will lead to an infinite flow of commits, probably real stage should contain some only conditions, etc.
Screenshots
GitLab Project Access Tokens page
GitLab Project CI/CD Settings menu, where to find Variables settings
Add project Variable pop-up

AppCenter: build if commit message contains a specific string

Is it possible to configure Microsoft AppCenter to set build frequency on "Build this branch on every push" but to build if commit message contains a specific string for each push.
you can add pre-build script, do your check then call exit 1 if needed,
reference: https://github.com/microsoft/appcenter/blob/1574250f1947cf2f595d1b63414199b167087bf0/sample-build-scripts/xamarin/app-displayname/appcenter-pre-build.sh#L64
You can use the following logic for this :
if ("git show $gitCommit || grep "regex" == false)
// { your code } do not deploy
else
// deploy

Azure Devops - run build only in the folder that have changes

I have a some spark jobs which are written on scala and build using maven.
Right now the follow a path like this
/src/job1/<<build data>>
/src/job2/<<build data>>
.....
This build data holds the code, pom.xml, tests and other thinks needed for each job pass to maven.
We have a root folder that has a father pom.xml that builds all the code, but I don't want to build all the code every time. I want to be able to test and build only the code for the jobs that changes.
The only way that I think is possible is to run build an tests only in the folders that changes was detected but I can't seem to do that without create one azure devops build for each folder, any ideas?
TL:DR - How to pass the path of folder that have changes in azure devops to the build process?
How to pass the path of folder that have changes in azure devops to the build process?
We could add a powershell scripts to check the folder or path, like:
$editedFiles = git diff HEAD HEAD~ --name-only
echo "$($editedFiles.Length) files modified:"
$editedFiles | ForEach-Object {
echo $_
Switch -Wildcard ($_ ) {
'/src/job1' {
Write-Output "##vso[task.setvariable variable=job1]True"
}
'/src/job2' {
Write-Output "##vso[task.setvariable variable=job2]True" }
}
}
This script sets variables which are then referenced in custom conditions in the pipeline build task or in the build pipeline:
and(succeeded(), eq(variables['job1'], 'True'))
You could check this similar thread for some details.
Hope this helps.
You can work around this by creating a script that will do the following:
Get the changeset/commit in the build to check which files are changed.
Based on the files changes, you define the logic to decide which folder it should build, run tests, etc.
This solution will require you to build all the logic to decide which folders to build and test.
Thanks for your inputs. I was able to do it with your inputs on git, I realized that we are using gitflow workflow and every time that we have pull request to the master branch (meaning deployment) a commit is created with starting "Merged PR", this way I can compare the latest two commits and check what changed.
How I'm doing:
# This part uses this to get the latest two pull requests hashes
$last_pr_commit=git log --grep="^Merged PR" -n 1 --pretty=format:"%h" --abbrev=200
$second_last_pr_commit=git log -n 1 --grep="^Merged PR" --oneline --abbrev=200 $last_pr_commit^...HEAD~2 --pretty=format:"%h"
# This get the path of the files
$result=git diff $last_pr_commit $second_last_pr_commit --name-only
And then I just build the ones that I'm interested.
ForEach ($line in $($result -split "`r`n"))
{
# In my case I only need the two first parts of path
$folderPath=$line.split('/')[0]+'/'+$line.split('/')[1]
if ($line.contains('.scala')){
# Running the tests and packaging
mvn package $folderPath
}
}
This is powershell but it can work with bash changing the for loop.
Thanks

Concourse: Use a semver resource to control which artifact to use from s3

My pipeline contains a task with the following pre-requisites
- get: version
trigger: true
params: { bump: patch }
passed: ["trigger_job [CI]"]
- get: sdk-package
passed: ["package_generation_job"]
params:
version: {path: "artifact_[I want to put the version here]"}
version is a semver stored in git; sdk-package is a build artifact stored in s3 where each run of the pipeline puts a new artifact using the version number as part of the name.
What I would like to do is used the version input to determine which version of the artifact is pulled from S3. Based on this I suspect that Concourse doesn't allow this, but I couldn't find a definitive answer.
This is not currently possible, you will have to download the artifact you want in a task script. You can pass the version into that task.

Trigger build from bitbucket to Jenkins based on Tags (Declarative Syntax)

I am looking for a help in Jenkins to trigger a build when specific tags(release.*) are pushed.
So far I got the way of skipping the deployment if there are no proper tags (https://jenkins.io/blog/2018/05/16/pipelines-with-git-tags/)
stage('Deploy') {
when { tag "release-*" }
steps {
echo 'Deploying only because this commit is tagged...'
sh 'make deploy'
}
}
Looks for something which will help me to trigger the builds from feature branch whenever a developer will push a tag.

Resources