Download file at specific commit with Bitbucket REST API - bitbucket

We are trying to find a way to download a single file from a Bitbucket project using the REST API at a specific commit. Currently, we have the ability to download a file at a specific branch:
https://stash.domain.com:8443/rest/api/1.0/projects/our_project/src/main/java/com/SomeFile.java?at=refs%2Fheads%2Fmaster
Note that the end of the URL, when decoded, contains the query parameter at=refs/heads/master, which refers to the master branch. This also works for specific tags:
https://stash.domain.com:8443/rest/api/1.0/projects/our_project/src/main/java/com/SomeFile.java?at=refs%2Ftags%2Ftesttag1
Here the query parameter at=refs/tags/testtag1 refers to the tag (commit) testtag1.
But because of the nature of our implementation, we would like to refer directly to a commit SHA-1 hash via the Bitbucket REST API. Is this possible?
Obviously, one ugly workaround would be to just add a tag to every commit. But this could bloat the repository and it also feels like an unnecessary hack.

With the help of this SO question, I found one of the answers which tipped me off to the correct syntax. Use this:
<URL>?at=commit_hash
For example:
https://stash.domain.com:8443/rest/api/1.0/projects/our_project/src/main/java/com/SomeFile.java?at=bed2dda5
Here is a table of three main endpoint types with the Bitbucket REST API:
query parameter | role
---------------------------------------------
refs/heads/master | specify master branch
refs/tags/someTag | specify 'someTag' tag
at=bed2dda5 | specify commit #bed2dda5

Related

Bitbucket - how to set branch permissions for given source/dest pair?

In Bitbucket cloud it's straightforward to set a branch permission to control who and how changes can be made, for example, consider who can modify the 'main' branch. We need more granularity and would like to be able to set up a rule based on both the source and destination branch.
Imagine we had the following branches:
releaseX
releaseY
featureA
featureB
Is it possible to specify a branching pattern or something that would apply different rules from release* -> main than feature* -> main? Maybe the 'Select branch By pattern' input takes a special pattern like s:release*,d:main etc..? Is this possible?
We also have access to the BB API if that helps somehow.

Using API how to find the parent branch in Bitbucket

I want to find the parent branches for a particular branch. Suppose I have created A branch from master and branch B from A. Now I want to find the parents for B like B->A->Master. I checked the Bitbucket API but there is no such a method available. When I pull the data for a branch there is no field which shows the parent branch details.
You can use regular git commands for that:
git branch --merged HEAD --sort=authordate
This lists the ancestor branches of the current working directory in chronological order (you can of course specify any other ref instead of HEAD) and would be great to use in a script or some automated tooling.
A very quick and dirty alternative way would be to just look at the regular output of git log:
git log --graph --decorate | egrep 'commit .* \('
This variation would maybe be interesting for a human to watch but too noisy for a script.

How to add more/custom data to be stored in jenkins rest api

My question is similar to this.
What I want is that when my pipelines run, I want to add some information in the job build so that when a REST API call is made it return existing info as well as info that I added to the job build-
Currently, the info present in this API has information like job names, build number, etc...
http://example.com/jenkins/<job_name>/<build_number>/api/json
I see there is a plugin that can be used to do this : Env Injector. But there is lot of effort to just add little info in existing API. It does not have good support of Jenkins pipeline and isn't that mainstream.
Other way is that I could just write a JSON file on the system where Jenkins is running and make it available over HTTP. This doesn't involve REST APIs but does what I want.
Is there any better way to do this?
If it's just metadata you can use the job description and parse it with Regex using Groovy
def jobDescription = job.getDescription();
// regex match of #tags, capture "tag" from "#tag"
def tagMatches = (jobDescription =~ /#(\S+)/)
Then iterate over tagMatches
tagMatches.each { match ->
}

Parameterize my repo url by parsing webhook request body/JSONpath

I am working on a multibranch pipeline Jenkins setup and build is triggered using webhook in Git.. Here I have selected Git Branch source as - Git.
When I push any change in git, webhook creates a request body with all push event details. How can I parse "git_http_url" value from this( which will have my git repo url). This value I can then use as ${myrepourl} in jenkins console. Basically I want avoid hardcoding the repo url, it should dynamically take using this parameter.
Please guide.
![webhook request body screenshots][2]][2]
[![attached my jenkins console branch source][1]][1]
[1]: https://i.stack.imgur.com/sdb0l.png
[2]: https://i.stack.imgur.com/icPP9.png
This looks like a not-very-good idea to begin with. I will start by explaining why, outlining the alternatives, and in the end suggesting a solution that might still work if you insist on doing this.
When you configure your pipeline, you need to provide it with Jenkinsfile. It can be pasted inside the configuration ("Pipeline script"), or you can provide a path to it so Jenkins can perform a checkout ("Pipeline script from SCM"). When doing the former, you have one Jenkinsfile, so different branches can't alter it (and so missing the point of having a multibranch). When doing the latter, even if you can parametrize the git repo, you still need to provide a path (as it won't arrive in github notification). In addition, I can trigger your build with my repo, but chances are your pipeline won't be able to properly build my repo anyway. So your pipeline can only build your repo, at which point it's a bit unclear why you insist on not providing your specific pipeline with a path to your specific repo that it specifically knows how to build.
Most people who need multibranch pipelines over Github use one of the plugins specifically written for this purpose, e.g. Github Multibranch plugin or Github organization. These plugins do all the job themselves: they sign up for notifications, process them, and start builds. They also update build status in Github for you.
Finally, if you insist on processing Github notifications yourself, you can use Generic Webhook Trigger plugin that will allow you to trigger the job by POST-ing to a specified URL with a token. This may look like this:
pipeline {
agent { node { label 'master'} }
triggers {
GenericTrigger(causeString: 'Generic Cause',
genericVariables: [
[key: 'DATA', value: '$'], //JSONPath expression meaning "everything"
[key: 'GITHUB_URL', value: '$.project.git_http_url']
],
printContributedVariables: false, // change to 'true' to see all the available variables in the console
printPostContent: false, // change to 'true' to see the dump of the POST data
silentResponse: false,
token: 'my_token')
}
As per the first configuration line, any JSON posted will get flattened and turned into pipeline variables, with a prefix you define (in this case, "DATA_"). E.g. the field git_http_url inside the field project in Github payload will be defined in the pipeline and available to you as DATA_project_git_http_url. As per second configuration line, it will also be available as GITHUB_URL.
You can test your pipeline with e.g.
curl -XPOST -H "Content-Type: application/json" 'http://<jenkins>/generic-webhook-trigger/invoke?token=my_token' --data '{"hello": "world"}'
In this case, the contributed variable will be DATA_hello and it will have the value of world. (The GITHUB_URL variable, naturally, won't be defined.)
If you want to turn this into real Github webhook processor, you need to make sure that Github notifs arrive to <jenkins>/generic-webhook-trigger/invoke?token=my_token. We use nginx for that, but there are many other options.

How to calculate ahead or behind branchs

Use libgit2sharp, how to calculate ahead or behind metrics. like this page https://github.com/libgit2/libgit2sharp/branches
How to calculate ahead or behind metrics
Each Branch bears a TrackingDetails property. This property exposes AheadBy and BehindBy nullable values (null will be returned when the branch has no upstream configuration or if the upstream branch does not exist).
Those values will represent the number of commits the local branch is ahead/behind compared to the upstream branch (ie. the remote branch being tracked).
This outputs similar results than git status -sb
like this page https://github.com/libgit2/libgit2sharp/branches
This page actually compares each branch of the upstream (ie. the one hosted on GitHub) repository against the current tip of the remote HEAD. This feature (comparing two local branches) is not available in LibGit2Sharp.
Provided you're interested with it, please feel free to open a feature request.
Update
A pull request (see #564) introducing a new method repo.ObjectDatabase.CalculateHistoryDivergence(Commit, Commit) is cooking up.
This will allow the user to determine the ahead-by and behind-by counts, along with the merge-base that's been used to calculate those distances.
For those searching (as of pygit2 v 0.27.4), the API is ahead_behind.
Sample code gist:
import pygit2
repo = pygit2.Repository('your-repo-path')
upstream_head = repo.revparse_single('origin/HEAD')
local_head = repo.revparse_single('HEAD')
diff = repo.ahead_behind(local_head.id, upstream_head.id)

Resources