How to push for any branch in CircleCI? - circleci

I want CircleCI to deploy for every branch that pushed.
The docs (https://circleci.com/docs/configuration/#deployment) state:
The branch field can also specify regular expressions, surrounded with / (e.g. /feature_.*/):
deployment:
feature:
branch: /feature_.*/
commands:
- ./deploy_feature.sh
I've tried branch: /*/, but this doesn't seem to work - I haven't got any builds on any branches!
I've also tried removing the branch: tag, but that raises a must contain a branch or a tag error.
Thanks for any ideas / help,
Max

branch: /.*/ seems to work
Although I'm not sure why

Related

Skip CircleCI Jobs on empty branches

When I push an empty branch to my GitHub repo (perhaps by creating a branch through the GitHub web UI), CircleCI sees it and runs all the tests for the commit at the tip of that branch.
This makes sense, but I've discovered an unfortunate side effect: the CircleCI jobs for the branch clobber the GitHub statuses for master with inaccurate information.
Here's the sequence of events:
I push commit A to master. This runs my whole CircleCI workflow and posts information on test success / failure for A to GitHub using the GitHub Status API.
I create a new branch, mybranch, using the GitHub UI. Its tip is also at commit A.
CircleCI runs all the tests for mybranch. These are also on commit A, so CircleCI re-posts statuses to the GitHub status API for commit A.
This might be OK, except that I have an optimization: I early-out of tests that shouldn't be affected by a PR branch. So if the branch contains no TypeScript files in its diff from master, I won't run the TypeScript tests. Unfortunately, this means that step 3 overrides the GitHub status for the full run on commit A with one that early outs (since there are no commits, there's no diff).
Here's what the "skip" logic looks like:
skip-job-if-no-ts:
description: Skips the rest of the job if files under ts/ have not been modified
steps:
- when:
condition:
not:
or:
# Always run all tests if this is a commit to master branch
- equal: [master, << pipeline.git.branch >>]
steps:
- run:
name: skip-job-if-no-ts
command: |
# Skip the rest of the job if ts/ wasn't modified
TS_CHANGED=$(git diff $(git merge-base HEAD origin/master) --name-only ts/)
if [ ! -n "$TS_CHANGED" ]; then
circleci-agent step halt
fi
How can I prevent CircleCI from running my job on an empty branch? I found an old discussion of this issue on the CircleCI forums, but it was closed with no comments.

Gitlab CI: How do I make `rules.changes` to compare changed file to main branch?

I am trying to create a base image for my repo that is optionally re-built when branches (merge requests) make changes to dependencies.
Let's say I have this pipeline configuration:
stages:
- Test
- Build
variables:
- image: main
Changes A:
stage: Test
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
changes:
- path/to/a
script:
- docker build -t a .
- docker push a
- echo 'image=a' > dotenv
artifacts:
reports:
dotenv: dotenv
Build:
stage: Build
image: $image
script:
- echo build from $image
Let's say I push to a new branch and the first commit changes /path/to/a, the docker image is build and pushed, the dotenv is updated and the Build job successfully uses image=a.
Now, let's say I push a new commit to the same branch. However, the new commit does not change /path/to/a so the Changes A job does not run. Now, the Build stage pulls the "wrong" default image=main while I would like it to still pull image=a since it builds on top of the previous commit.
Any ideas on how to deal with this?
Is there a way to make rules.changes refer to origin/main?
Any other ideas on how to achieve what I am trying to do?
Is there a way to make rules.changes refer to origin/main?
Yes, there is, since GitLab 15.3 (August 2022):
Improved behavior of CI/CD changes with new branches
Improved behavior of CI/CD changes with new branches
Configuring CI/CD jobs to run on pipelines when certain files are changed by using rules: changes is very useful with merge request pipelines.
It compares the source and target branches to see what has changed, and adds jobs as needed.
Unfortunately, changes does not work well with branch pipelines.
For example, if the pipeline runs for a new branch, changes has nothing to compare to and always returns true, so jobs might run unexpectedly.
In this release we’re adding compare_to to rules:changes for both jobs and workflow:rules, to improve the behavior in branch pipelines.
You can now configure your jobs to check for changes between the new branch and the defined comparison branch.
Jobs that use rules:changes:compare will work the way you expect, comparing against the branch you define.
This is useful for monorepos, where many independent jobs could be configured to run based on which component in the repo is being worked on.
See Documentation and Issue.
You can use it only as part of a job, and it must be combined with rules:changes:paths.
Example:
docker build:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
changes:
paths:
- Dockerfile
compare_to: 'refs/heads/branch1'
In this example, the docker build job is only included when the Dockerfile has changed relative to refs/heads/branch1 and the pipeline source is a merge request event.
There is a project setting, which defines how your MR pipelines are setup. This is only working for Merge requests and can be found in Settings -> Merge Requests under the section Merge options
each commit individually - nothing checked
this means, each commit is treated on its own, and changes checks are done against the triggering commit on it's own
Enabled merged results pipeline
This will merge your MR with the target branch before running the CI Jobs. This also will evaluate all your changes, and take a look at all of them within the MR and not commit wise.
Merge trains
This is a whole different chapter, and for this usecase not relevant. But for completeness i have to mention it see https://gitlab.com/help/ci/pipelines/merge_trains.md
What you are looking for is Option 2 - Merged pipeline results. but as i said, this will only work in Merge Request pipelines and not general pipelines. So you would also need to adapt your rules to something like:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
changes:
- path/to/a
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

prevent github pipeline from being affected

I have a fastlane file in my ios project. When I increase the version number of the project and submit the code to github, the pipeline is constantly triggered. To solve this problem, I want to print the version number in another file and ignore that file. will this solve my problem? is there any other solution ?
I suppose your pipeline is triggered via GitHub Actions.
Look on .github/workflows/ you should have something like
on:
push:
You can exclude when to launch the pipeline and define when trigger it.
For example don't run for commit on main and launch it on tag starting with v:
on:
push:
branches-ignore:
- main
tags:
- v*

I can't use push_to_git_remote() in fastlane

I have an issue with gitlab, gitlab-ci and fastlane. In fastlane, I am using :
def increment_build_and_commit
incrementBuildNumber()
commit_version_bump(message: 'build number bump [skip ci]')
push_to_git_remote(
remote: 'origin_rw',
remote_branch: ENV['CI_COMMIT_BRANCH']
)
end
So I want to increase build number and commit. So it does the job with:
incrementBuildNumber(),
commit_version_bump(message: 'build number bump [skip ci]')
But when running, it fails at push_to_git_remote
[!] Exit status of command 'git push origin_rw HEAD:HEAD --tags
--set-upstream' was 1 instead of 0. error: The destination you provided is not a full refname (i.e., starting with "refs/"). We
tried to guess what you meant by:
Looking for a ref that matches 'HEAD' on the remote side.
Checking if the being pushed ('HEAD') is a ref in "refs/{heads,tags}/". If so we add a corresponding
refs/{heads,tags}/ prefix on the remote side. Neither worked, so we
gave up. You must fully qualify the ref. hint: The part of the
refspec is a commit object. hint: Did you mean to create a new branch
by pushing to hint: 'HEAD:refs/heads/HEAD'? error: failed to push
some refs to '**********.git'
Some of you have any clues what to do and how to solve this problem? As I am going to be a google machine on that, but unfortunetly can't find the solution.
Thanks in advance!!
This happens because gitlab-ci checkouts git commit instead of git branch and you enter detached HEAD state.
There are few ways to get around this:
1) Use CI provided value. For GitLab I would recommend using CI_PIPELINE_IID. Downside is that you cannot control it and if you migrate your project to other repository it will start from 1 again.
2) Checkout git branch before making commit. Downside is that if other developer pushes to the same branch, your pipeline will continue with wrong source code.
3) Commit version number bump manually.

Keep track of which git branch is currently deployed to a Heroku server

I know there is a http deploy hook I can use but unfortunately it does not submit the branch name, here is what it does submit:
{"head"=>"7021419", "app"=>"appname", "git_log"=>"commit message", "action"=>"home", "url"=>"site url", "prev_head"=>"1d844b0", "controller"=>"account_sessions", "user"=>"heroku#user.com", "head_long"=>"7031429230228988d8f3312fa9e74d77b6c1bc14"}
I tried using the head or head_long to figure out the branch name with:
git branch --contains SHA
Which worked, but it is not 100% accurate as the same SHA could be in multiple branches. Same can be said about:
git reflog show --all | grep 7021419
I am pretty sure it is impossible to get the current branch name from within the deployed app as the branch deployed to Heroku is always the "master" branch. I was hoping I can send the deploy callback hook to another server and store the deployment record somewhere.
1. Detecting only
If it's just about heads, use
git rev-list --no-walk --glob=refs/heads
with a bit of --format and grep logic tacked on
2. Tracking locally
The simplest way would be using a tag.
Push the tag like a normal branch:
git push herokuremote tagname:publicbranchname
Unfortunately, that would just push the tag, not a branch... ; read on for alternative
(note I don't know/use heroku, so I don't know the naming conventions, sorry)
3. Symbolic branch reference
If you don't mind using a bit of plumbing, you can name a local ref as the one deployed. You can have a symbolic ref for the purpose:
git update-ref -m "deployed release candidate" --no-deref refs/heads/deployed master
If the same SHA is in multiple branches, they are effectively the same branch (at least at that point in time). If you're sure that SHA is the last commit of a branch, you can find it in .git/refs/heads/* where * is a list of files whose names correspond to branch names and contents are the SHAs.
It seems like you might be able to solve this recording problem by not using their API. Wrapping your deploy script (or Heroku's deploy binary, or a post-push hook) should give you the flexibility you need to notify a different service for record keeping.

Resources