{"id":22180689,"url":"https://github.com/jftuga/jenkins_notes","last_synced_at":"2025-03-24T18:46:13.825Z","repository":{"id":117699278,"uuid":"604402021","full_name":"jftuga/jenkins_notes","owner":"jftuga","description":"My personal notes about Jenkins","archived":false,"fork":false,"pushed_at":"2024-02-12T22:19:42.000Z","size":14,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-29T23:29:57.404Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jftuga.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-21T01:33:42.000Z","updated_at":"2023-02-24T18:39:59.000Z","dependencies_parsed_at":"2024-02-12T23:30:39.477Z","dependency_job_id":"1c45432f-0bbe-40fb-a403-dd9686b66f17","html_url":"https://github.com/jftuga/jenkins_notes","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jftuga%2Fjenkins_notes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jftuga%2Fjenkins_notes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jftuga%2Fjenkins_notes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jftuga%2Fjenkins_notes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jftuga","download_url":"https://codeload.github.com/jftuga/jenkins_notes/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245332080,"owners_count":20598102,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-02T09:19:17.612Z","updated_at":"2025-03-24T18:46:13.797Z","avatar_url":"https://github.com/jftuga.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Jenkins Notes\n\n## My personal notes about Jenkins\n\nThis is my self-study guide on how to use `Jenkins` to deploy `AWS SAM templates`.  It uses the [Jenkins Multibranch Pipelines](https://www.jenkins.io/doc/book/pipeline/multibranch/)\nto deploy into different environments (dev, prod).  It also sends a Slack notification when the job starts and when the job completes.  For the build environment, it uses the [Python 3.9](https://gallery.ecr.aws/sam/build-python3.9)\nimage available from the [SAM Image Repository](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-image-repositories.html).\n\n## Jenkins Configuration\n\n### Branch Sources\n\n* Credentials: `read-only user`\n\n| Behavior | Settings | Notes |\n| -------- | -------- | ----- |\n| Discover Branches | Exclude branches that are also files as PRs | reduces redundant effort\n| Discover pull requests from origin | Merging the pull request with the current target branch | best option for my work flow; example: merge feature-branch to main\n| Discover pull requests from forks | Merging the pull request with the current target branch | *(See above)*\n| Trust | Forks in the same account | best option for my work flow\n| Filter by name | Exclude | *(any research such as Spikes)*\n\n* Property strategy: `all branches get the same properties`\n\n### Build Configuration\n\n* Mode: `by Jenkinsfile`\n* Script Path: `build/Jenkinsfile`\n\n\n### Scan Multibranch Pipeline Triggers\n\n* Build when a change is pushed: `checked`\n* All other options: `unchecked`\n\n### Orphaned Item Strategy\n\n* Discard old items: `checked`\n\n\n## Example Notes\n* In the example file, the following replacements will be needed:\n* * `project-name`: the code repo name (for example)\n* * `user`: a valid username for the github repo\n* * `user@example.com`: contact info\n\n___\n\n## Searching for complete sections\n\n[ripgrep](https://github.com/BurntSushi/ripgrep) is a grep alternative that is faster and has more [features](https://github.com/BurntSushi/ripgrep/blob/master/FAQ.md). For example, it honors `.gitignore` when deciding which files to inspect.  One option that I learned about recently is the `--multiline` option which permits matches to span multiple lines.  I like to use this with the `(?s)` modifier (aka `--multiline-dotall`).  This causes a dot *(within a regular expression)* to also match newline characters. You can install `ripgrep` via [homebrew](https://formulae.brew.sh/formula/ripgrep). Although the package name is `ripgrep`, the command is simply `rg`.\n\nI like using the following invocation for finding *code blocks*.  For example, I have a `Jenkinsfile` that has a stage named `Configure assume role`, but I'd like to see the entire stage and not just that one line.  I really just want to see the specific code block matching the entire stage.\n\nTo accomplish this, I can run this command:\n\n```bash\n$ rg --multiline '(?s)stage.*?Configure assume role.*?}.*?}.*?}' Jenkinsfile\n\n57:    stages {\n58:        stage('Configure assume role') {\n59:            steps {\n60:                sh 'mkdir -p /root/.aws'\n61:                withCredentials([file(credentialsId: 'my-creds-jenkins', variable: 'config')]) {\n62:                    sh \"cp \\$config /root/.aws/config\"\n63:                }\n64:            }\n65:            steps {\n66:                sh 'echo this is step 2...'\n67:                }\n```\n\nThis is a regular expression that:\n* matches newlines via `(?s)`\n* searches for anything starting with `stage` followed by anything else *(such as non-alphanumeric characters)*\n* followed by my desired search string: `Configure assume role`\n* followed by three ending curly braces which can occur **on multiple lines**. This will obviously be dependent on how and where you want to end your own reg expr match.\n* Note that `.*?` will match the shortest possible string, while using `.*` will match the longest. If I did not include the `?` then this command would match until the end of file, which is not the desired outcome.\n* * *See also:* [Minimal or non-greedy quantifiers](https://www.ibm.com/docs/en/netcoolomnibus/8.1?topic=library-minimal-non-greedy-quantifiers)\n\nAnother optimization is to use regular expression `repetition qualifiers`.  In this case, I need three consecutive `}` to end the match but what if I needed to match 15 braces? This method would get ugly.  You can use the syntax of `{n}` where `n` is the number of matches you want.  This immediately follows the regular expression that you want it to match on, which may also need to be wrapped between `()`.  You can also use `{min,max}` to set lower and upper bounds.\n\nI can shorten the command by using the following `repetition qualifier` syntax to get the same result.  Note that I wrapped `.*?` inside of parenthesis so that the `{3}` qualifier will work correctly.  This makes it easier to see smaller or larger portions of the stage by adjusting this value as needed.\n\n```bash\nrg --multiline '(?s)stage.*?Configure assume role(.*?}){3}' Jenkinsfile\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjftuga%2Fjenkins_notes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjftuga%2Fjenkins_notes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjftuga%2Fjenkins_notes/lists"}