Linters Hooks Pipelines
Automation to Save Your Bacon Elliot Jordan End-User Platform Security Nordstrom “I’m not really a software developer.
I just think I’m a software developer because I develop software.”
— Arjen van Bochoven ‣ Package sources ‣ Scripts and extension plist, yaml, json, shell, python attributes ‣ AutoPkg recipes/ shell, python overrides ‣ MDM profiles plist, shell, python plist ‣ Munki repos ‣ Documentation plist, python, shell text, markdown, reStructuredText Mac Software "Dev Ops" Admin Developer Reducing errors
Streamlining development
Automating tedious tasks Ground Rules
Protected "master" branch
Peer review
Remote Git hosting
Production code in Git
Code standards Linters Linters
Linters Linters
Linters Linters
Linters Atom + Shellcheck
Linters Atom + Shellcheck
Terminal $ brew install shellcheck ==> Downloading https://homebrew.bintray.com/bottles/ shellcheck-0.6.0_1.mojave.bottle.tar.gz ==> Pouring shellcheck-0.6.0_1.mojave.bottle.tar.gz ! /usr/local/Cellar/shellcheck/0.6.0_1: 8 files, 7.2MB $ which shellcheck /usr/local/bin/shellcheck ⌘C $
Linters Atom + Shellcheck
Linters Atom + Shellcheck
Linters Atom + Shellcheck
Linters Atom + Shellcheck
Linters Atom + Shellcheck
Linters Atom + Shellcheck
Linters Atom + Shellcheck
⌘V
Linters Atom + Shellcheck
Linters Atom + Shellcheck
Linters Atom + Shellcheck
Linters Atom + Shellcheck
Click to learn more!
Linters Atom + Shellcheck
Linters Atom + Shellcheck
Typo caught
Linters Atom + Shellcheck
Suggestions for improving resiliency
Linters Atom + Shellcheck
Deprecated syntax callouts
Linters Atom + Shellcheck
Generally accepted practices
Linters Atom + Shellcheck
Useless cat!
Photo: Byron Chin
Linters Atom + Shellcheck
Linters Atom + Shellcheck
Linters Shellcheck + zsh
‣ Shellcheck doesn't currently support zsh
However:
‣ That might change someday
‣ Bash scripts should work fine in Catalina
Linters Atom + Pylint
Linters Atom + Pylint
Linters Atom + Pylint
Linters Atom + Pylint
Linters Atom + Pylint
Linters Atom + Pylint
Linters Atom + Pylint
Linters Atom + Pylint
Linters Atom + Pylint
Linters Atom + Pylint
Linters Fine-Tuning Linters
E0611
Linters Fine-Tuning Linters
E0611
Linters Fine-Tuning Linters
# pylint: disable=E0611
Linters Fine-Tuning Linters
# pylint: disable=no-name-in-module
Terminal $ pylint example2.py No config file found, using default configuration ************* Module example2 C: 1, 0: Missing module docstring (missing-docstring) E: 3, 0: No name 'CFPreferencesCopyAppValue' in module 'CoreFoundation' (no-name-in-module) C: 6, 0: Constant name "munki_repo" doesn't conform to UPPER_CASE naming style (invalid-name)
------Your code has been rated at -13.33/10 (previous run: -13.33/10, +0.00)
$
Linters Fine-Tuning Linters
# pylint: disable=no-name-in-module
# pylint: enable=no-name-in-module
Linters Fine-Tuning Linters
# pylint: disable=E0611
Linters Fine-Tuning Linters
Linters Fine-Tuning Linters
# shellcheck disable=SC2115
Linters Fine-Tuning Linters
# shellcheck disable=SC2115
Linters Linter Limitations
‣ Installed per-app and per-Mac ‣ Not easily distributed across a team ‣ Suggestions are optional
Linters Autoformatters
‣ Python black, yapf, autopep8, isort ‣ Go gofmt ‣ Ruby rubocop
Linters Python Black
Linters Python Black
Linters Python Black
Linters Python Black
Linters Fine-Tuning Autoformatters
# fmt: off
# fmt: on
Linters When to Avoid Autoformatters
‣ Submitting a very small change to a repo ‣ Contributing to a new repo for the first time ‣ If the maintainers strongly prefer their own style
Linters Autoformatter Limitations
‣ You may not agree with the style choices (but you get used to it) ‣ Can be quite jarring to convert a project to use autoformatters for the first time (large diffs) ‣ Not easily distributable across team without help from other frameworks
Linters Hooks Hooks
git commit -a -m "My great commit"
fix the issue and try again pre-commit hook(s)
exit exit nonzero zero
commit fails commit succeeds
Linters Hooks Hooks
git commit -a -m "My great commit"
fix the issue and try again pre-commit hook(s)
exit exit nonzero zero
commit fails commit succeeds
Linters Hooks Hooks
pre-commit hook(s)
Linters Hooks Installing Pre-Commit
Terminal $ brew install pre-commit Updating Homebrew... ==> Downloading https://homebrew.bintray.com/bottles/pre-commit-1.17.0.moja ve.bottle.tar.gz ==> Pouring pre-commit-1.17.0.mojave.bottle.tar.gz ! /usr/local/Cellar/pre-commit/1.17.0: 703 files, 8.9MB $ which pre-commit /usr/local/bin/pre-commit $ pre-commit --version pre-commit 1.17.0 $
Linters Hooks Installing Pre-Commit
Terminal $ cd ~/path/to/git_repo $ touch .pre-commit-config.yaml $ open -a Atom .pre-commit-config.yaml $
Linters Hooks Installing Pre-Commit
Terminal
$ cd ~/path/to/git_repo .pre-commit-config.yaml $ touch .pre-commit-config.yaml repos:$ open -a Atom .pre-commit-config.yaml - repo:$ https://github.com/pre-commit/pre-commit-hooks rev: v2.2.3 hooks: - id: no-commit-to-branch
Linters Hooks Installing Pre-Commit
Terminal $ cd ~/path/to/git_repo $ touch .pre-commit-config.yaml $ open -a Atom .pre-commit-config.yaml $ pre-commit install pre-commit installed at .git/hooks/pre-commit $
Linters Hooks Installing Pre-Commit
Terminal $ git branch * master $ git commit -am "Add pre-commit config" Don't commit to branch...... Failed $ git checkout -b pre-commit A .pre-install-config.yaml Switched to a new branch 'pre-commit' $ git commit -am "Add pre-commit config" Don't commit to branch...... Passed [pre-commit 48f2745] Add pre-commit config 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .pre-install-config.yaml $
Linters Hooks Configuring Pre-Commit
.pre-commit-config.yaml repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.2.3 hooks: - id: no-commit-to-branch
Linters Hooks Configuring Pre-Commit
.pre-commit-config.yaml repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.2.3 hooks: - id: no-commit-to-branch - id: check-added-large-files args: [--maxkb=100] - id: check-merge-conflict
- repo: https://github.com/python/black rev: 19.3b0 hooks: - id: black
Linters Hooks Configuring Pre-Commit
.pre-commit-config.yaml repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.2.3 hooks: - id: no-commit-to-branch P - id: check-added-large-files Text Editor Pre-Commit args: [--maxkb=100] - id: check-merge-conflict
- repo: https://github.com/python/black rev: 19.3b0 hooks: - id: black
Linters Hooks Configuring Pre-Commit
.pre-commit-config.yaml repos: - repo: https://github.com/pre-commit/ - repo: https://github.com/ambv/black pre-commit-hooks rev: 19.3b0 rev: v2.2.1 hooks: hooks: - id: black - id: check-added-large-files args: [--maxkb=200] - repo: https://github.com/asottile/ - id: check-byte-order-marker blacken-docs - id: check-case-conflict rev: v0.5.0 - id: check-docstring-first hooks: - id: check-merge-conflict - id: blacken-docs - id: check-symlinks additional_dependencies: - id: check-yaml [black==19.3b0] - id: mixed-line-ending - id: no-commit-to-branch - id: trailing-whitespace args: [--markdown-linebreak-ext=md]
Linters Hooks Configuring Pre-Commit
.pre-commit-config.yaml repos: - repo: https://github.com/pre-commit/ - repo: https://github.com/ambv/black pre-commit-hooks rev: 19.3b0 rev: v2.2.1 hooks: hooks: - id: black - id: check-added-large-files args: [--maxkb=200] - repo: https://github.com/asottile/ - id: check-byte-order-marker blacken-docs - id: check-case-conflict rev: v0.5.0 - id: check-docstring-first hooks: - id: check-merge-conflict - id: blacken-docs - id: check-symlinks additional_dependencies: - id: check-yaml [black==19.3b0] - id: mixed-line-ending - id: no-commit-to-branch - id: trailing-whitespace args: [--markdown-linebreak-ext=md]
Linters Hooks Updating Pre-Commit Hooks
Terminal $ pre-commit autoupdate Updating https://github.com/pre-commit/pre-commit-hooks...updating v2.2.0 -> v2.2.3. Updating https://github.com/python/black...[INFO] Initializing environment for https://github.com/python/black. updating stable -> 19.3b0. Updating https://github.com/asottile/blacken-docs...[INFO] Initializing environment for https://github.com/asottile/blacken-docs. updating v1.0.0 -> v1.1.0. $
Linters Hooks Configuring Pre-Commit
.pre-commit-config.yaml repos: - repo: https://github.com/pre-commit/ - repo: https://github.com/ambv/black pre-commit-hooks rev: 19.3b0 rev: v2.2.1 hooks: hooks: - id: black - id: check-added-large-files args: [--maxkb=200] - repo: https://github.com/asottile/ - id: check-byte-order-marker blacken-docs - id: check-case-conflict rev: v0.5.0 - id: check-docstring-first hooks: - id: check-merge-conflict - id: blacken-docs - id: check-symlinks additional_dependencies: - id: check-yaml [black==19.3b0] - id: mixed-line-ending - id: no-commit-to-branch - id: trailing-whitespace args: [--markdown-linebreak-ext=md]
Linters Hooks Pre-Commit Hooks for Mac Admins
https://github.com/homebysix/pre-commit-macadmin
Linters Hooks Pre-Commit Hooks for Mac Admins
~/Developer/pkg-sources/.pre-commit-config.yaml repos: - repo: https://github.com/homebysix/pre-commit-macadmin rev: v1.3.0 hooks: - id: check-munkipkg-buildinfo - id: check-outset-scripts - id: check-plists
Linters Hooks Pre-Commit Hooks for Mac Admins
~/Developer/pkg-sources/.pre-commit-config.yaml repos: - repo: https://github.com/homebysix/pre-commit-macadmin rev: v1.3.0 hooks: - id: check-munkipkg-buildinfo - id: check-outset-scripts - id: check-plists
Linters Hooks Pre-Commit Hooks for Mac Admins
~/Developer/pkg-sources/.pre-commit-config.yaml repos: - repo: https://github.com/homebysix/pre-commit-macadmin rev: v1.3.0 hooks: - id: check-munkipkg-buildinfo - id: check-outset-scripts - id: check-plists
Linters Hooks Pre-Commit Hooks for Mac Admins
~/Developer/public-autopkg-recipes/.pre-commit-config.yaml repos: - repo: https://github.com/homebysix/pre-commit-macadmin rev: v1.3.0 hooks: - id: check-autopkg-recipes args: ['--recipe-prefix=com.github.yourusername.', '--strict'] - id: forbid-autopkg-overrides - id: forbid-autopkg-trust-info
Linters Hooks Pre-Commit Hooks for Mac Admins
~/Developer/public-autopkg-recipes/.pre-commit-config.yaml repos: - repo: https://github.com/homebysix/pre-commit-macadmin rev: v1.3.0 hooks: - id: check-autopkg-recipes args: ['--recipe-prefix=com.github.yourusername.', '--strict'] - id: forbid-autopkg-overrides - id: forbid-autopkg-trust-info
Linters Hooks Pre-Commit Hooks for Mac Admins
~/Developer/public-autopkg-recipes/.pre-commit-config.yaml repos: - repo: https://github.com/homebysix/pre-commit-macadmin rev: v1.3.0 hooks: - id: check-autopkg-recipes args: ['--recipe-prefix=com.github.yourusername.', '--strict'] - id: forbid-autopkg-overrides - id: forbid-autopkg-trust-info
Linters Hooks Pre-Commit Hooks for Mac Admins
~/Developer/company-autopkg-overrides/.pre-commit-config.yaml repos: - repo: https://github.com/homebysix/pre-commit-macadmin rev: v1.3.0 hooks: - id: check-autopkg-recipes args: ['--recipe-prefix=com.example.autopkg.', '--override-prefix=local.', '--strict'] - id: check-autopkg-recipe-list - id: check-plists
Linters Hooks Pre-Commit Hooks for Mac Admins
~/Developer/company-autopkg-overrides/.pre-commit-config.yaml repos: - repo: https://github.com/homebysix/pre-commit-macadmin rev: v1.3.0 hooks: - id: check-autopkg-recipes args: ['--recipe-prefix=com.example.autopkg.', '--override-prefix=local.', '--strict'] - id: check-autopkg-recipe-list - id: check-plists
Linters Hooks Pre-Commit Hooks for Mac Admins
~/Developer/company-munki-repo/.pre-commit-config.yaml repos: - repo: https://github.com/homebysix/pre-commit-macadmin rev: v1.3.0 hooks: - id: check-munki-pkgsinfo args: [ '--required-keys', 'category', 'description', 'developer', 'name', 'version', '--catalogs', 'stable', 'testing', '--categories', 'Communication', 'Printers', 'Productivity', 'Security' '--'] - id: check-munkiadmin-scripts - id: check-plists
Linters Hooks Collaborating with Pre-Commit
Git Remote
.pre-commit-config.yaml
brew install pre-commit brew install pre-commit git pull git pull git push pre-commit install pre-commit install
.pre-commit-config.yaml .pre-commit-config.yaml .pre-commit-config.yaml
Collaborators run pre-commit install once for each Git repo.
Linters Hooks Pre-Commit Hook Limitations
‣ Hooks are typically written for a general audience ‣ Updating repo rev is a minor recurring task ‣ Hooks can still be bypassed
‣ If contributor doesn't set up local repo with pre-commit install
‣ If contributor skips hooks using git commit --no-verify
‣ If contributor commits using GitLab/GitHub web UI
Linters Hooks Pipelines Pipelines
Git Remote
Linters Hooks Pipelines Pipelines
product build code syncing to inspection prod
"master" branch
Linters Hooks Pipelines Pipelines
code product syncing to inspection build prod
"master" branch peer review
• linting • MunkiPkg builds • autoformatters • sync repo to cloud hosting • makecatalogs • pre-commit hooks • import artifacts into Munki • code signing • org-specific test scripts
Continuous Integration Continuous Deployment
Linters Hooks Pipelines Pipelines
code product syncing to inspection build prod
"master" branch peer review
• linting • MunkiPkg builds • autoformatters • sync repo to cloud hosting • makecatalogs • pre-commit hooks • import artifacts into Munki • code signing • org-specific test scripts
Continuous Integration Continuous Deployment
Linters Hooks Pipelines Basic CI Config
Linters Hooks Pipelines Basic CI Config
Linters Hooks Pipelines Basic CI Config
.gitlab-ci.yml One-line linting command plutil_linting: tags: - macOS script: /usr/bin/plutil -lint *.plist
Linters Hooks Pipelines Basic CI Config
good.plist
Linters Hooks Pipelines Basic CI Config
bad_char.plist
Linters Hooks Pipelines Basic CI Config
bad_key.plist
Linters Hooks Pipelines Basic CI Config
bad_tag.plist
Linters Hooks Pipelines Basic CI Config
Linters Hooks Pipelines Enforcing Peer Review
Linters Hooks Pipelines Enforcing Peer Review
Linters Hooks Pipelines Enforcing Peer Review
Linters Hooks Pipelines Enforcing Peer Review
Linters Hooks Pipelines Enforcing Peer Review
Linters Hooks Pipelines Enforcing Peer Review
Linters Hooks Pipelines Enforcing Peer Review
Linters Hooks Pipelines Enforcing Peer Review
Linters Hooks Pipelines Enforcing Peer Review
Linters Hooks Pipelines Enforcing Peer Review
Linters Hooks Pipelines Enforcing Peer Review
Linters Hooks Pipelines Git Workflow
add commits create dev branch merge request
peer review merge to master master branch
Linters Hooks Pipelines But... What to Use Pipelines For?
‣ Prevent anything that would blow up production
‣ badly formatted plist
‣ absence of required keys
‣ missing shebangs for scripts in Munki pkginfo files
Linters Hooks Pipelines But... What to Use Pipelines For?
‣ Things best done in the cloud
‣ Running commands like makecatalogs (Note: Does not require macOS)
‣ Syncing to cloud storage
Linters Hooks Pipelines But... What to Use Pipelines For?
‣ Tasks that require elevated access or permissions
‣ Syncing to cloud storage
‣ Signing apps or profiles using a private key
Linters Hooks Pipelines But... What to Use Pipelines For?
‣ Whatever you want!
‣ Catching mistakes made previously
‣ Enforcing code/formatting standards you care about
‣ Preventing rogue files, categories, identifiers, etc.
Linters Hooks Pipelines Pipeline Examples
.gitlab-ci.yml pre_commit: script: /usr/local/bin/pre-commit run --all-files except: - master
(Assumes your runner has pre-commit, python3, and git installed.)
Linters Hooks Pipelines Pipeline Examples Munki Repo
‣ Lint plists, including both pkginfo and manifest files ‣ Ensure required keys are present (including org-specific like category, description) ‣ Ensure catalogs/categories are org-standard ‣ Ensure pkg installers have blocking apps (empty list OK) ‣ Ensure icon file is present ‣ Ensure testing catalog listed before stable in manifests ...and a few more
Linters Hooks Pipelines Pipeline Examples Munki Repo
.gitlab-ci.yml plutil_linting: tags: - macOS script: /usr/bin/plutil -lint *.plist
Linters Hooks Pipelines Pipeline Examples Munki Repo
.gitlab-ci.yml plutil_linting: tags: - macOS Two-line script for plutil script: - /usr/bin/plutil -lint pkgsinfo/*/*.plist - /usr/bin/plutil -lint manifests/*
Linters Hooks Pipelines Pipeline Examples Munki Repo
.gitlab-ci.yml plutil_linting: tags: - macOS script: - /usr/bin/plutil -lint pkgsinfo/*/*.plist - /usr/bin/plutil -lint manifests/* Reference to a separate linting script munki_linting: script: /usr/bin/python ci/munki_linting.py
Linters Hooks Pipelines Pipeline Examples
ci/munki_linting.py #!/usr/bin/python import os import plistlib import sys from glob import glob EMONSTRATION exitcode = 0 D pkginfo_files = globOR("./pkgsinfo/**/*.plist") # os.walk might be better F NLY for path in pkginfo_files: O print("Linting %s..." % path) pkginfo = plistlib.PreadPlistURPOSES(path) # add try/except if pkginfo and "uninstall_script" in pkginfo: # use a function for complex tests if pkginfo.get("uninstall_method") != "uninstall_script": print((extremely"ERROR: %s simplified,has an uninstall not error script, resistent, but thebad uninstallbut easy tomethod walk through)" "is set to %s." % (path, pkginfo.get("uninstall_method"))) exitcode = 1 # more pkginfo tests here sys.exit(exitcode)
Linters Hooks Pipelines Pipeline Examples
ci/munki_linting.py #!/usr/bin/python import os import plistlib import sys from glob import glob Make a list of the files you want to check exitcode = 0 pkginfo_files = glob("./pkgsinfo/**/*.plist") # os.walk might be better for path in pkginfo_files: print("Linting %s..." % path) pkginfo = plistlib.readPlist(path) # add try/except
if pkginfo and "uninstall_script" in pkginfo: # use a function for complex tests if pkginfo.get("uninstall_method") != "uninstall_script": print("ERROR: %s has an uninstall script, but the uninstall method " "is set to %s." % (path, pkginfo.get("uninstall_method"))) exitcode = 1 # more pkginfo tests here sys.exit(exitcode)
Linters Hooks Pipelines Pipeline Examples
ci/munki_linting.py #!/usr/bin/python import os import plistlib import sys from glob import glob exitcode = 0 pkginfo_files = glob("./pkgsinfo/**/*.plist") # os.walk might be better Parse them with plistlib for path in pkginfo_files: print("Linting %s..." % path) pkginfo = plistlib.readPlist(path) # add try/except
if pkginfo and "uninstall_script" in pkginfo: # use a function for complex tests if pkginfo.get("uninstall_method") != "uninstall_script": print("ERROR: %s has an uninstall script, but the uninstall method " "is set to %s." % (path, pkginfo.get("uninstall_method"))) exitcode = 1 # more pkginfo tests here sys.exit(exitcode)
Linters Hooks Pipelines Pipeline Examples
ci/munki_linting.py #!/usr/bin/python import os import plistlib import sys from glob import glob exitcode = 0 pkginfo_files = glob("./pkgsinfo/**/*.plist") # os.walk might be better for path in pkginfo_files: print("Linting %s..." % path) pkginfo = plistlib.readPlist(path) # add try/except Run your checks, set exitcode if pkginfo and "uninstall_script" in pkginfo: # use a function for complex tests if pkginfo.get("uninstall_method") != "uninstall_script": print("ERROR: %s has an uninstall script, but the uninstall method " "is set to %s." % (path, pkginfo.get("uninstall_method"))) exitcode = 1 # more pkginfo tests here sys.exit(exitcode)
Linters Hooks Pipelines Pipeline Examples
ci/munki_linting.py #!/usr/bin/python import os import plistlib import sys from glob import glob exitcode = 0 pkginfo_files = glob("./pkgsinfo/**/*.plist") # os.walk might be better for path in pkginfo_files: print("Linting %s..." % path) pkginfo = plistlib.readPlist(path) # add try/except
if pkginfo and "uninstall_script" in pkginfo: # use a function for complex tests if pkginfo.get("uninstall_method") != "uninstall_script": print("ERROR: %s has an uninstall script, but the uninstall method " "is set to %s." % (path, pkginfo.get("uninstall_method"))) exitcode = 1 # more pkginfo tests here Exit with the appropriate code sys.exit(exitcode)
Linters Hooks Pipelines Pipeline Examples Munki Repo
.gitlab-ci.yml plutil_linting: tags: - macOS script: - /usr/bin/plutil -lint pkgsinfo/*/*.plist - /usr/bin/plutil -lint manifests/* munki_linting: script: /usr/bin/python ci/munki_linting.py
Linters Hooks Pipelines Pipeline Examples Munki Repo
.gitlab-ci.yml plutil_linting: tags: - macOS script: - /usr/bin/plutil -lint pkgsinfo/*/*.plist - /usr/bin/plutil -lint manifests/* munki_linting: script: /usr/bin/python ci/munki_linting.py Python Black autoformatting (x3!) black_format: script: /usr/local/bin/black .
Linters Hooks Pipelines Pipeline Examples Munki Repo
.gitlab-ci.yml plutil_linting: Tag to target a specific runner tags: - macOS script: - /usr/bin/plutil -lint pkgsinfo/*/*.plist - /usr/bin/plutil -lint manifests/* munki_linting: script: /usr/bin/python ci/munki_linting.py Does not require macOS black_format: script: /usr/local/bin/black .
Linters Hooks Pipelines Pipeline Examples Munki Repo
.gitlab-ci.yml # ...continued... makecatalogs: script: /usr/local/munki/makecatalogs Run job only on a specific branch only: - master
Linters Hooks Pipelines Pipeline Examples Munki Repo
.gitlab-ci.yml # ...continued... Sync master branch to AWS S3 s3_sync: variables: REPO_BUCKET: yourmunkirepo script: - aws s3 sync ./catalogs "s3://$REPO_BUCKET/catalogs" --delete --exclude=".*" - aws s3 sync ./icons "s3://$REPO_BUCKET/icons" --delete --exclude=".*" - aws s3 sync ./pkgsinfo "s3://$REPO_BUCKET/pkgsinfo" --delete --exclude=".*" - aws s3 sync ./manifests "s3://$REPO_BUCKET/manifests" --delete --exclude=".*" # The pkgs folder is synced separately. only: - master
Linters Hooks Pipelines Pipeline Examples Munki Repo
product build syncing to prod code inspection "master" branch
Linters Hooks Pipelines Pipeline Examples Munki Repo
makecatalogs aws s3 sync linting scripts "master" branch
Linters Hooks Pipelines CI/CD Pipeline Limitations
‣ Setting up and maintaining runners is significant administrative overhead ‣ Requiring peer review can be a stress on your teammates' time and attention
Linters Hooks Pipelines Let's Review
Linters Hooks Pipelines Let's Review
Mac Software "Dev Ops" Admin Developer
Linters Hooks Pipelines Let's Review
Protected "master" branch
Peer review
Remote Git hosting
Production code in Git
Code standards
Linters Hooks Pipelines Let's Review
Linters Hooks Pipelines Let's Review
Terminal $ git commit -a -m "Apply shellcheck suggestions" Check for added large files...... Passed Check for byte-order marker...... Passed Check for case conflicts...... Passed Check docstring is first...... (no files to check)Skipped Check for merge conflicts...... Passed Check for broken symlinks...... (no files to check)Skipped Check Yaml...... Passed Mixed line ending...... Passed Don't commit to branch...... Passed Trim Trailing Whitespace...... Passed black...... (no files to check)Skipped blacken-docs...... (no files to check)Skipped Check Munki Pkginfo Files...... (no files to check)Skipped Check MunkiAdmin Scripts...... (no files to check)Skipped Check Plists...... (no files to check)Skipped [pre-commit-gitlab-ci 9dc7318] Remove non-working config 1 file changed, 18 deletions(-)
$
Linters Hooks Pipelines Let's Review
Terminal $ git commit -a -m "Apply shellcheck suggestions" Check for added large files...... Passed Check for byte-order marker...... Passed Check for case conflicts...... Passed Check docstring is first...... (no files to check)Skipped Check for merge conflicts...... Passed Check for broken symlinks...... (no files to check)Skipped Check Yaml...... Passed Mixed line ending...... Passed Don't commit to branch...... Passed Trim Trailing Whitespace...... Passed black...... (no files to check)Skipped blacken-docs...... (no files to check)Skipped Check Munki Pkginfo Files...... (no files to check)Skipped Check MunkiAdmin Scripts...... (no files to check)Skipped Check Plists...... (no files to check)Skipped [pre-commit-gitlab-ci 9dc7318] Remove non-working config 1 file changed, 18 deletions(-)
$ git push
Linters Hooks Pipelines Let's Review
Git Remote
Additional linting
Custom check scripts
Linters Hooks Pipelines Let's Review
Git Remote
Peer review
Linters Hooks Pipelines Let's Review
Git Remote
Merge to master branch
Linters Hooks Pipelines Let's Review
Git Remote
Build products
Linters Hooks Pipelines Let's Review
Git Remote
Sync repo/products with prod
Linters Hooks Pipelines ! " homebysix # elliotjordan
Thank you!
Notes and Links: https://bit.ly/2S1cRCC
Linters Hooks Pipelines