Specify file_path while triggering AWS codebuil - github

I have created AWS codebuild pipeline. It triggers automatically whenever I push to the Master branch.
Now, I want to trigger it only when something is changed in Dockerfile. Below is my project structure:
casestudy
|
|
|->Docker->Dockerfile
|-> Infrastructure -> infrastructure-files
Below is the screenshot of codebuild webhook filter:
If I push something to Dockerfile, the build is not getting triggered.
Kindly note that if I remove the file_path filter the build triggers with every push on the master branch.
My code is placed on GIthub.

I believe you want file_path = docker/Dockerfile
or perhaps, to prevent things like otherdir/docker/Dockerfile from triggering it, file_path = ^docker/Dockerfile
If you go through the Github web interface and view the repository's webhooks (Settings->Webhooks) and click "Edit" next to the webhook created by CodeBuild and then scroll down to the bottom where it says "Recent Deliveries", by clicking the "..." next to one of those you can actually see the request sent to the webhook. You will see in there the list of files modified by the commit, and they will not have a leading slash (e.g. "docker/Dockerfile")

Related

Custom GitHub Checks With Jenkins Pipeline

I need to create a custom check for tests and to trigger the check through the jenkins pipeline.
for example:
stage("tests"){ \\ Tests go here. \\ Notify github pr check the status }
I tried several plugins and some articles I've read about it but it didn't work.
any suggestions?

Only run GitHub Actions manually while blocking Pull Request

I have a set of GitHub Actions configured to block pull requests from being merged until the Actions complete successfully. However, every time a new commit is pushed to a PR, the Actions are run again, which can be very wasteful if the author is not yet ready to merge, and intends to make future changes. Is there any way to have a GitHub Action still block a PR being merged but also not run the Action automatically?
With this recent update you can now convert pull requests back to draft status. So you could do that when you need to make changes and disable the CI for drafts. Then convert the draft to a pull request after the changes are complete to rerun CI.
on: pull_request
jobs:
build:
if: github.event.pull_request.draft == 'false'
runs-on: ubuntu-latest
steps:
...
One workaroound would be for the Action to look for a specific comment (for example: "[TO MERGE]: this commit is about ...), and:
return immediately if '[TO MERGE]' is not found, minimizing the action overhead on each commit
go on with checks, if '[TO MERGE]' is found.

GitHub Actions: Are there security concerns using an external action in a workflow job?

I have a workflow that FTPs files by using an external action from someuser:
- name: ftp deploy
uses: someuser/ftp-action#master
with:
config: ${{ secrets.FTP_CONFIG }}
Is this a security concern? For example could someuser change ftp-action#master to access my secrets.FTP_CONFIG? Should I copy/paste their action into my workflow instead?
If you use ftp-action#master then every time your workflow runs it will fetch the master branch of the action and build it. So yes, I believe it would be possible for the owner to change the code to capture secrets and send them to an external server under their control.
What you can do to avoid this is use a specific version of the action and review their code. You can use a commit hash to refer to the exact version you want, such as ftp-action#efa82c9e876708f2fedf821563680e2058330de3. You could use a tag if it has release tags. e.g. ftp-action#v1.0.0
Although, this is maybe not as secure because tags can be changed.
Alternatively, and probably the most secure, is to fork the action repository and reference your own copy of it. my-fork/ftp-action#master.
The GitHub help page does mention:
Anyone with write access to a repository can read and use secrets.
If someuser does not have write access to the repository, there should be no security issue.
As commented below, you should specify the exact commit of the workflow you are using, in order to make sure it does not change its behavior without your knowledge.

Can I skip an AWS CodePipeline build?

I am currently developing a personal project on master. Every time I push to origin master a build is triggered on CodePipeline. As I am the only developer working on this project and don't want to bother with branches at this stage it would be nice to skip unnecessary builds. I wouldn't mind pushing to another branch, but it's a small annoyance.
CodeShip allows you to skip a build by including --skip-ci in your commit message. Is something like this possible with CodePipeline?
None of my Google searches have yielded results. The CodePipeline documentation makes no mention of such a feature either.
A valid reason for not wanting to build a certain commit is when you use CodeBuild to generate a commit for you. For example, I have some code on the master branch which passes all the tests. I then want to update the changelog, package.json version and create a git tag on a new commit and push it back to the CodeCommit repo.
If I do this on Codebuild, the version-commit triggers another build! Given the contents of the commit does not materially change the behaviour of the code, there is no need to build & test this commit.
Besides all of this, Amazon should be looking at the features in the marketplace and attempting to provide at least feature-parity. Adding a RegEx check for "skip-ci" to the CodeBuild trigger-code would take a few hours to implement, at most.
By default codepipeline creates a cloudwatch event which triggers your pipeline on all changes of the specific branch.
What you can do is to set this cloudwatch event to trigger a lambda function. This function can check whether it is necessary to build this commit and start your CodePipeline.
Here is an example of how to achieve this:
https://aws.amazon.com/blogs/devops/adding-custom-logic-to-aws-codepipeline-with-aws-lambda-and-amazon-cloudwatch-events/
Here is a simple example for lambda function. It checks if the last commit has no [skip-CI] in its message and after that executes the pipeline.
Keep in mind, that this code checks only the last commit if your change was a series of commits you might want to check everything between oldCommitId and commitId.
const AWS = require('aws-sdk');
const codecommit = new AWS.CodeCommit();
const codepipeline = new AWS.CodePipeline();
exports.handler = async (event) => {
const { detail: { repositoryName, commitId, oldCommitId } } = event
const { commit } = await codecommit.getCommit({
commitId,
repositoryName
}).promise()
if(commit.message.search(/\[skip-CI\]/) === -1) {
const { pipelineExecutionId } = await codepipeline.startPipelineExecution({
name: 'your-pipeline-name'
}).promise()
console.log(`Pipeline have started. Execution id: ${pipelineExecutionId}!`)
} else {
console.log('Pipeline execution is not required')
}
return;
};
This isn't a feature offered by CodePipeline at this time.
I'd be curious to know why you view some builds as unnecessary. Do you push a sequence of commits and only want a build against the last commit? This may be more applicable in a team environment, but I would tend to want a build for every commit so I don't find myself in a situation where I push code and pick up and build someone else's broken code for the first time in my build.
I would suggest a manual review stage in your pipeline before it builds. Then you can just approve it when you are ready to build.

Prevent mercurial push during a jenkins build

I have a jenkins job that runs some tests on a mercurial repo, and if successful tags the local repo with a 'stable' tag and then pushes this back to the main repo. The issue I'm having is that if someone pushes changesets while the build is running, then I cannot push the 'stable' tag.
I was wondering if there was a way to set the remote repo to read-only while the build is running, then make it 'push-able' once the build finishes?
Thanks,
Vackar
Preventing the push is probably not what you want (and it's almost pretty much impossible). The promise of a DVCS like Mercurial or git is that there's no locking -- it's a step forward.
Have you considered having Jenkins just pull and update before it merges? You can still tag the proper revision. Something like this:
jenkins checks out the code and notes the revision id it's building
jenkins does the build, runs the tests, etc. and everything goes well
jenkins does a hg pull to get the latest from the server
jenkins does a hg tag -m "build number $BUILD_NUMBER" --revision X --force stable
jenkins does a hg push
Then there's (almost) no time between that final pull, tag, and push, but the tag still goes on the revision that was actually build -- because you saved that revision hash id from when you first pulled.
I've just been looking for something similar. In our case, Jenkins is performing a merge, running an extensive suite of tests and once they all pass, pushing the merged code back to the repository. So it takes ~1 hour and fails if a developer pushes while the job is executing (it can't do the final push).
I couldn't find a ready-made solution, so ended up writing a mercurial hook which checks whether the job is building (using the REST API) before allowing the push.
You'll need access to your remote mercurial repository, but other than that, it's not too complex.
Add the following to your-remote-repo/.hg/hgrc:
[hooks]
pretxnchangegroup.DisablePushDuringJenkinsBuild= python:.hg/disable_push_if_building_hook.py:check_jenkins
[jenkins]
url=http://path-to-jenkins
jobs=jenkins-job-name[,comma-separated, for-multiple, jobs]
And make sure this python script is in your-remote-repo/.hg/
import json, urllib2
from mercurial import util
TEN_SECONDS = 10
def check_jenkins(ui, repo, node, **kwargs):
jenkins_url = ui.config('jenkins', 'url', default=None, untrusted=False)
jenkins_jobs = ui.config('jenkins', 'jobs', default=None, untrusted=False)
if not jenkins_url:
raise util.Abort('Jenkins hook has not been configured correctly. Cannot find Jenkins url in .hg/hgrc.')
if not jenkins_jobs:
raise util.Abort('Jenkins hook has not been configured correctly. Cannot find Jenkins jobs in .hg/hgrc.')
jenkins_jobs = [x.strip() for x in jenkins_jobs.split(',')]
for job in jenkins_jobs:
job_url = jenkins_url + '/job/' + job + '/lastBuild/api/json'
ui.write('Checking if job is running at URL: %s\n' % job_url)
try:
job_metadata = json.load(urllib2.urlopen(job_url, timeout = TEN_SECONDS))
if 'building' in job_metadata and job_metadata['building']:
raise util.Abort('Jenkins build "%s" is in progress. Pushing is disabled until it completes.' % job_metadata['fullDisplayName'])
except urllib2.URLError, e:
raise util.Abort('Error while trying to poll Jenkins: "%s"' % e)
return False # Everything is OK, push can be accepted