Is it possible to permanently update the value of a TeamCity build parameter as a result of a custom run? - teamcity

Is it possible to permanently update the value of a build parameter as a result of a custom run?
For example, consider a build which is configured to have the build number format:
%Major%.%Minor%.%Patch%.%build.counter%
Major, Minor and Patch and defined in the build configuration to have certain values. For the sake of an example, lets say this gives a build number of 3.1.2.36.
It is possible to change the build number by clicking '...' next to run and then changing the value of one of the params. Changing Minor from 1->2 and patch from 2->0 would give the next build the number 3.2.0.37.
I'm not overly concerned that 37 hasn't be reset to 0, but the problem is that the next build which is triggered (not as a result of a custom run) will have the build number 3.1.2.38 which is a lower number. Is it possible that when you run a custom build and change the numbers that the new values are persisted?
I am looking for a way that users with no TeamCity admin rights can cause the version number to be incremented according to the changes they have made.
We are running v8.1.2 (build 29993).

To fix the issue I used the TeamCity REST API. I created a new build param of type prompt called 'ReleaseType' which can be either Patch, Minor or Major. This is then used in this command line script which is set up as a TeamCity build step:
IF "%ReleaseType%"=="Major" (
set /a newVersion=%VersionMajor%+1
curl -v --request PUT -d 0 --Header "Content-Type: text/plain" http://username:password#servername:8080/httpAuth/app/rest/projects/%system.teamcity.projectName%/parameters/VersionMinor
curl -v --request PUT -d 0 --Header "Content-Type: text/plain" http://username:password#servername:8080/httpAuth/app/rest/projects/%system.teamcity.projectName%/parameters/VersionPatch
)
IF "%ReleaseType%"=="Minor" (
set /a newVersion=%VersionMinor%+1
curl -v --request PUT -d 0 --Header "Content-Type: text/plain" http://username:password#servername:8080/httpAuth/app/rest/projects/%system.teamcity.projectName%/parameters/VersionPatch
)
IF "%ReleaseType%"=="Patch" (
set /a newVersion=%VersionPatch%+1
)
curl -v --request PUT -d %%newVersion%% --Header "Content-Type: text/plain" http://username:password#servername:8080/httpAuth/app/rest/projects/%system.teamcity.projectName%/parameters/Version%ReleaseType%
curl -v --request PUT -d 0 --Header "Content-Type: text/plain" http://username:password#servername:8080/httpAuth/app/rest/buildTypes/id:%dep.Dependant_BuildName.system.teamcity.buildType.id%/settings/buildNumberCounter
This increments the specified build number and resets downstream version parts to 0.
For example, a minor version increase on 3.2.12.122 goes to 3.3.0.0.
Note - in my particular example above the build counter is reset on a dependant build and not the configuration which is running. This may or may not be what you are after. Replace
%dep.Dependant_BuildName.system.teamcity.buildType.id%
with
%system.teamcity.buildType.id%
if you want to reset the current running build configuration.

Related

Gitlab CI/CD - sending comments/alerts to the gitlab UI?

Currently I have this line in my .gitlab-ci.yml file:
if (( $coverage < $MIN_COVERAGE )) ; then echo "$coverage% of code coverage below threshold of $MIN_COVERAGE%" && exit 1 ; else exit 0 ; fi
$coverage is the test coverage of the code, determined with pytest-cov
$MIN_COVERAGE is a specified minimum level of test coverage which $coverage shouldn't drop below
Currently, this causes the pipeline to fail if, for instance, coverage is 70% and min_coverage is 80%. A message is also printed to the terminal: "$coverage% of code coverage below threshold of $MIN_COVERAGE%"
However, this message is only displayed in the terminal of the gitlab job, so if someone wanted to see why and by how much their pipeline failed they would need to go into the job terminal and look at the output.
Instead of having this echo to the job terminal, is there a way to get this message to output somewhere on the gitlab UI?
Here's how to create a new Merge Request Note/Comment using the GitLab API.
script:
# Project -> Settings -> Access Tokens, Create token with API scope.
# Project -> Settings -> CI/CD -> Variables, Store as CI_API_TOKEN
# GET /merge_requests?scope=all&state=opened&source_branch=:branch_name
- |
merge_request_iid=$( \
curl --request GET \
--header "PRIVATE-TOKEN: ${CI_API_TOKEN}" \
"${CI_API_V4_URL}/merge_requests?scope=all&state=opened&source_branch=${CI_COMMIT_REF_NAME}" | \
jq .[0].iid \
)
# POST /projects/:id/merge_requests/:iid/notes
- json_data='{"body":"Your message, here"}'
- |
echo $json_data |
curl --request POST \
--header "PRIVATE-TOKEN: ${CI_API_TOKEN}" \
--header "Content-Type: application/json" \
--data #- \
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${merge_request_iid}/notes"
If you have a GitLab Premium subscription or higher, you can use metrics reports to expose any metric, including coverage percentage, in the MR UI.
In all tiers of GitLab, coverage visualization is also available, but it's unclear to me if this displays the overall coverage percentage.
Alternatively, you can use the API to add comments to the merge request (you can get the MR ID from predefined variables in the job). However, you will need to supply an API token to the CI job -- you cannot use the builtin job token to add comments.
In addition, you can use the GitLab CLI tool (glab) in your CI pipeline:
comment-mr:
image: registry.gitlab.com/gitlab-org/cli:latest
variables:
GIT_STRATEGY: none
GITLAB_TOKEN: $MR_AUTOMATION_TOKEN # Project -> Settings -> Access Tokens (api, api_read scopes)
script:
- if [ -z "$CI_OPEN_MERGE_REQUESTS" ]; then echo "No opened MR"; exit 0; fi
- glab mr --repo "$CI_PROJECT_PATH" comment $(echo "$CI_OPEN_MERGE_REQUESTS" | cut -d '!' -f2) --unique=true
--message "🐋 Branch-based docker image - \`$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-branch\`"

Unable to list regex protected branch using Gitlab API

I am trying to get GitLab protected branches of a project using curl API request, getting all the relevant branches of type "xyz", "xyz-*".
But I am unable to get the branch that has a "/" in its name.
Using below curl request which is failing for branch "release/R*" :
curl -H "Content-Type: application/json" --header "PRIVATE-TOKEN: <TOKEN>" "https://xyz.gitlab.com/tools/gitlab/api/v4/projects/492/protected_branches/'release/R*'"
It gives an output {"error":"404 Not Found"}
Need help to get the output for all the branches, irrespective of the regex, if possible.
To use in a curl request the name of a branch that contains / you need to use its encoded form %2F
Change
release/R
To
release%2FR
To test it, try to query for a single branch (https://docs.gitlab.com/ee/api/branches.html#get-single-repository-branch)
For a branch with name E.g. release/Rated
curl --header "PRIVATE-TOKEN: <TOKEN>" "https://example.com/gitlab/api/v4/projects/<project_id>/repository/branches/release%2FRated"

Why Ansible-Tower is ignoring extra variables?

Trying to lunch a job workflow via REST API and passing extra variables for the playbook to consume, but returned body shows that provided variables are put in ignored_fields section.
Used POSTMAN and CURL to run the templates both returned the same result
CURL command
curl -X POST http://172.16.0.97/api/v2/job_templates/8/launch/ -H "Content-Type: application/json" -H "Authorization: Bearer Je
gxwfQrdKQXoRUtNWtWFz62FX5bTy" -d "{\"extra_vars\": {\"vendor\":\"juniper\"}}"
Returned body
{"job":34,"ignored_fields":{"extra_vars":{"vendor":"juniper"}},"id":34,"type":"job","url":"/api/v2/jobs/34/","related":{"created_by":"/api/v2/users/1/","modified_by":"/api/v2/users/1/","labels":"/api/v2/jobs/34/labels/","inventory":"/api/v2/inventories/1/","project":"/api/v2/projects/7/","extra_credentials":"/api/v2/jobs/34/extra_credentials/","credentials":"/api/v2/jobs/34/credentials/","unified_job_template":"/api/v2/job_templates/8/","stdout":"/api/v2/jobs/34/stdout/","job_events":"/api/v2/jobs/34/job_events/","job_host_summaries":"/api/v2/jobs/34/job_host_summaries/","activity_stream":"/api/v2/jobs/34/activity_stream/","notifications":"/api/v2/jobs/34/notifications/","job_template":"/api/v2/job_templates/8/","cancel":"/api/v2/jobs/34/cancel/","create_schedule":"/api/v2/jobs/34/create_schedule/","relaunch":"/api/v2/jobs/34/relaunch/"},"summary_fields":{"inventory":{"id":1,"name":"Demo Inventory","description":"","has_active_failures":true,"total_hosts":1,"hosts_with_active_failures":1,"total_groups":0,"groups_with_active_failures":0,"has_inventory_sources":false,"total_inventory_sources":0,"inventory_sources_with_failures":0,"organization_id":1,"kind":""},"project":{"id":7,"name":"Cox-Phase3","description":"","status":"successful","scm_type":"git"},"job_template":{"id":8,"name":"Port Flap","description":""},"unified_job_template":{"id":8,"name":"Port Flap","description":"","unified_job_type":"job"},"created_by":{"id":1,"username":"admin","first_name":"","last_name":""},"modified_by":{"id":1,"username":"admin","first_name":"","last_name":""},"user_capabilities":{"delete":true,"start":true},"labels":{"count":0,"results":[]},"extra_credentials":[],"credentials":[]},"created":"2019-05-14T09:43:16.115516Z","modified":"2019-05-14T09:43:16.177517Z","name":"Port Flap","description":"","job_type":"run","inventory":1,"project":7,"playbook":"main.yml","forks":0,"limit":"","verbosity":1,"extra_vars":"{}","job_tags":"","force_handlers":false,"skip_tags":"","start_at_task":"","timeout":0,"use_fact_cache":false,"unified_job_template":8,"launch_type":"manual","status":"pending","failed":false,"started":null,"finished":null,"elapsed":0.0,"job_args":"","job_cwd":"","job_env":{},"job_explanation":"","execution_node":"","controller_node":"","result_traceback":"","event_processing_finished":false,"job_template":8,"passwords_needed_to_start":[],"ask_diff_mode_on_launch":false,"ask_variables_on_launch":false,"ask_limit_on_launch":false,"ask_tags_on_launch":false,"ask_skip_tags_on_launch":false,"ask_job_type_on_launch":false,"ask_verbosity_on_launch":false,"ask_inventory_on_launch":false,"ask_credential_on_launch":false,"allow_simultaneous":false,"artifacts":{},"scm_revision":"","instance_group":null,"diff_mode":false,"job_slice_number":0,"job_slice_count":1,"credential":null,"vault_credential":null}
According to the fine manual, AWX (and thus Tower) version 3.0 and greater has made extra_vars more strict: https://docs.ansible.com/ansible-tower/latest/html/userguide/job_templates.html#ug-jobtemplates-extravars
If you are running a version greater than 3.0, you will need to either turn on playbook survey or set ask_variables_on_launch=True for that template
In my case, I'm using curl -L ... and the payload got lost after the redirect. Be sure to double check that if you find the extra_vars still gets ignored after ensuring ask_variables_on_launch=True.
Tangentially related to the API when utilizing the AWX and Tower CLI I ran into a similar issue of variables not being taken when launching jobs. The solution was that on the Job Template in Tower the "Prompt on Launch" setting needed to checked for the variable to pass through. So much time wasted on such a simple miss.

TeamCity API setting configuration parameters

I have configuration parametr current_build_date (User Defined Parameter) I want just to set this parameter to current date by API TeamCity.
On docs I have seen this:
http://teamcity:8111/httpAuth/app/rest/buildTypes/<buildTypeLocator>/parameters/<parameter_name>
I know my Build configuration ID, but I can't understand how by this to make buildTypeLocator.
I assume result will be something like this:
curl -u Login:Password \
-X PUT \
-d 'valueOfMyParam' \
-H 'Content-Type: text/plain' \
http://teamcity:8111/httpAuth/app/rest/buildTypes/<buildTypeLocator>/parameters/current_build_date
I will realy appreciate if somebody who knows TeamCity API will help me with this problem.
I made attempt just to pass instead of buildTypeLocator my Build configuration ID and I got ERROR:
[17:08:25][Step 3/3] Error has occurred during request processing (Not Found).
[17:08:25][Step 3/3] Error: jetbrains.buildServer.server.rest.errors.NotFoundException: No project found by name or internal/external id 'BuildConfigurationID'.
If there are any problems or ambiguities with my question please add comment, i'll try to fix it.
If you browse the REST API endpoints in a browser you'll be able to see the format of the build locator.
Visit http://teamcity:8111/httpAuth/app/rest/buildTypes/ and you'll see the entries have a href attribute that contains the buildLocator (generally a property:value combination)
You'll then be able to navigate using that url / communicate via the API
Hope this helps
I solved problem: build type locator was id:Build configuration ID
current_build_date=`date +%%Y-%%m-%%d:%%H:%%M:%%S`
echo $current_build_date;
curl -u Login:Password \
-X PUT \
-d $current_build_date \
-H 'Content-Type: text/plain' \
https://teamcity.billing.ru/httpAuth/app/rest/buildTypes/id:Build
configuration ID/parameters/current_build_date

Update to-many association

Having a many-to-many relationship between users and groups. I would like to know how to update this relationship with SDR. This is what I've tried so far after reading the docs.
curl -X POST -H 'Content-Type: text/uri-list' -d 'http://localhost:8080/rest/users/5' http://localhost:8080/rest/groups/1/users
Expected result: Add user 5 to group 1.
Actual result: 405 Method Not Allowed.
curl -X PUT -H 'Content-Type: text/uri-list' -d 'http://localhost:8080/rest/users/5' http://localhost:8080/rest/groups/1/users
Expected result: Replace all members of group 1 with user 5.
Actual result: Works as expected.
curl -X PUT -H 'Content-Type: text/uri-list' -d #members.txt http://localhost:8080/rest/groups/1/users
Where the file members.txt has:
http://localhost:8080/rest/users/5
http://localhost:8080/rest/users/6
http://localhost:8080/rest/users/7
Expected result: Replace all members of group 1 with the users 5, 6 and 7.
Actual result: Only last user (in this case 7) gets added.
Could someone provide an example on how to ADD a single URI to an association?. Also if possible, how to add or replace an association with multiple URIs?
After re-reading the documentation, it does indeed say POST should add to the collection.
My experience has been to use PATCH to add to the collection.
To further the answer: You should be able to use PUT CONTENT-TYPE: text/uri-list with a content body having multiple URIs. Each URI is separated by a line break "\n"
Try this:
curl -v -X POST -H "Content-Type: text/uri-list" -d "http://localhost:8080/rest/users/5" http://localhost:8080/rest/groups/1/users

Resources