class: center, middle, inverse # Automating the Vox Pupuli Yak Shaving ## Automate all the yak shaving! ??? --- ## $ whoami
* Tim 'bastelfreak' Meusel * Puppet Contributor since 2012 * Merging stuff on [Vox Pupuli](https://voxpupuli.org/) (Puppet Community) since 2015 * Vox Pupuli Project Management Committee member ??? * --- ## $ whoami
* Robert 'flipez' Müller * Ruby Developer since 2013 * Builds clouds at Hetzner * Also builds Rails apps and tunes football tables ??? * --- class: center, middle, inverse # What's this Vox Pupuli thingy? ??? * lets have a look on the daily tasks a maintainer can do to keep modules in shape --- .left-column[ ## Vox Pupuli ] .right-column[ * Amount of Vox Pupuli members with merge permissions ![img](contributors.svg) ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * based on github org * who of you is part of that group? * who uses vox pupuli modules? * who doesn't know what vox is? --- class: center, middle, inverse # The path of a Open Source Maintainer... ## What do we do? ??? * lets have a look on the daily tasks a maintainer can do to keep modules in shape --- background-image: url(yakshaving.jpg) background-size: cover ??? * lets start with yak shaving --- .left-column[ ## Yak shaving ### Dependencies ] .right-column[ ![imagefoo](stdlib7.png) ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? Puppetlabs releases a new major version of stdlib --- .left-column[ ## Yak shaving ### Dependencies ] .right-column[ ![imagefoo](deps.png) ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * This leads to an interesting challenge * All puppet modules have an upper version boundary * At least in acceptance tests those boundaries are enforced, we need to update it * vox pupuli has 105 modules that depend on stdlib --- .left-column[ ## Yak shaving ### Dependencies ] .right-column[ ![imagefoo](puppet.png) ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * of course the same applies for the puppet version * Dear puppet: a headsup info for a new release would be dope --- .left-column[ ## Yak shaving ### Dependencies ] .right-column[ ![imagefoo](rhel.png) ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * and it applies for all the operating systems --- .left-column[ ## Yak shaving ### Dependencies ### Labels ] .right-column[ ![imagefoo](labels.png) ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * We've a basic set of labels that are identical across all modules * sometimes we add / remove labels * sometimes we get repositories migrated to us --- .left-column[ ## Yak shaving ### Dependencies ### Labels ### Modulesync ] .right-column[ * Many files are identical across our modules * CONTRIBUTING.md, rspec configuration * Many files are very similar * .travis.yml, Gemfile, Rakefile ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## Yak shaving ### Dependencies ### Labels ### Modulesync ] .right-column[ * modulesync was initially developed by Puppet Inc. * Now maintained by Vox Pupuli * a template directory + configuration file for every module ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## Yak shaving ### Dependencies ### Labels ### Modulesync ### Releases ] .right-column[ ![img](releases.png) ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * We've currently 124 modules on the forge * we need to release modules on a regular basis --- class: center, middle, inverse # The path of a Open Source Maintainer... ## What do we actually do? ??? --- .left-column[ ## Reviews ] .right-column[ * We have many pull requests ![img](prs.png) * [All open PRs](https://github.com/pulls?q=is%3Aopen+is%3Apr+user%3Avoxpupuli+archived%3Afalse+sort%3Acreated-desc) * [All open PRs with green CI](https://github.com/pulls?utf8=%E2%9C%93&q=is%3Aopen+is%3Apr+user%3Avoxpupuli+archived%3Afalse+sort%3Acreated-desc+status%3Asuccess) * [All open PRs with green CI and no merge conflicts](https://github.com/pulls?utf8=%E2%9C%93&q=is%3Aopen+is%3Apr+user%3Avoxpupuli+archived%3Afalse+status%3Asuccess+sort%3Aupdated-desc+-label%3Amerge-conflicts) ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * `with no merge conflicts` is handled by our labels * github search doesn't allow --- .left-column[ ## Reviews ### More labels ] .right-column[ ![img](labels2.png) ![img](labels3.png) ![img](labels4.png) * New feature? `enhancement` label * Bug / Bugfix? `bug` label * Breaking change? `backwards-incompatible` label * Additional work required? `needs-work` label ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## Reviews ### More labels ] .right-column[ Filtering: * labels like `needs-feedback`, `needs-work`, `tests-fail`, `needs-docs`, `beginner-friendly`, `needs-rebase` help us to sort pull requests and issues by grouping them Changelog: * labels like `bug`, `enhancement`, `backwards-incompatible` help us to generate a CHANGELOG.md ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * show the CHANGELOG.md * or https://github.com/voxpupuli/puppet-zabbix/blob/master/CHANGELOG.md --- .left-column[ ## Reviews ### More labels ### Email Addresses ] .right-column[ * Ensure that an author has their email address in Git and github.com in sync * Otherwise GitHub fails to account the contribution properly ![img](email.png) ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## Reviews ### More labels ### Email Addresses ### Templates ] .right-column[ * Ensure that new templates are always [epp](https://puppet.com/docs/puppet/latest/lang_template_epp.html), not [erb](https://puppet.com/docs/puppet/latest/lang_template_erb.html) * Epp templates have proper scopes and datatypes ![img](epp.png) ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- class: center, middle, inverse # Let us solve all our problems! ??? --- .left-column[ ## VPT ] .right-column[ .smallimg[ ![imagefoo](automate.jpg) ] ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * explain VPT means Vox Pupuli Tasks --- .left-column[ ## VPT ### Automate daily tasks ] .right-column[
### "There is this script. Do you think we can improve it?" * Checks supported OS ranges * Checks supported Puppet range * Sort repos into categories based on * managed modules files * voxpupuli/plumbing repo * forge releases * information in files in every repository ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- count: false .left-column[ ## VPT ### Automate daily tasks ] .right-column[
### "There is this script. Do you think we can improve it?" * Checks supported OS ranges * Checks supported Puppet range * Sort repos into categories based on * managed modules files * voxpupuli/plumbing repo * forge releases * information in files in every repository ## Uhm, I guess ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## VPT ### Automate daily tasks ] .right-column[ ![img](vpt_dashboard.png) ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## VPT ### Automate daily tasks ] .right-column[ ## The to-do list ![img](vpt_sort_1.png) * Refreshed every 6 hours ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## VPT ### Automate daily tasks ] .right-column[ ## The to-do list ![img](vpt_sort_2.png) * Refreshed every 6 hours ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## VPT ### Automate daily tasks ] .right-column[ ## The repository view ![img](vpt_repo.png) ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- class: center, middle, inverse # What else did we do? ??? --- class: center, middle, inverse
??? --- .left-column[ ## VPT ### Automate daily tasks ### Architecture ] .right-column[ ![img](VPT-overview.jpg) ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## VPT ### Automate daily tasks ### Architecture ] .right-column[ ```ruby case type when 'pull_request' # Ignore events which are triggered by the bot return if payload.dig('sender', 'id').to_i == 53_702_691 if Repository.notably? payload['repository']['name'] @processor = GithubEvent::PullRequest.new(payload) end when *known_but_ignoreable_events true else Raven.capture_message("Unknown Hook Received: #{type}", extra: payload) end ``` ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## VPT ### Automate daily tasks ### Architecture ] .right-column[ ```ruby def validate(saved_changes) # Don't run through the validaten, if only the eligable_for_comment attribute got updated return if saved_changes.keys.sort == %w[eligable_for_comment].sort && !mergeable.nil? # if the pull request is now closed, dont attach/remove labels/comments return if closed? label = Label.needs_rebase if mergeable == true ensure_label_is_detached(label) elsif mergeable == false repository.ensure_label_exists(label) ## # We only add a comment if we addded a label. If the label already is present # we also already added the comment. So no need for a new one. add_comment(I18n.t('c.needs_rebase', author: author)) if ensure_label_is_attached(label) elsif mergeable.nil? UpdateMergeableWorker.perform_in(1.minute.from_now, repository.name, number, id, saved_changes) end end ``` ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## VPT ### Automate daily tasks ### Architecture ] .right-column[
] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## VPT ### Automate daily tasks ### Architecture ] .right-column[
] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## VPT ### Automate daily tasks ### Architecture ] .right-column[ ![img](pr_label_3.png) ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## VPT ### Automate daily tasks ### Architecture ] .right-column[
] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## VPT ### Automate daily tasks ### Architecture ] .right-column[
] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- class: center, middle, inverse # What else can we do? ## What do you want us to do? What are your usecases? ??? --- .left-column[ ## VPT ### Automate daily tasks ### Architecture ### Lookout ] .right-column[ * Automate more labeling on issues and pull requests ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * All examples we showed earlier could be automated --- count: false .left-column[ ## VPT ### Automate daily tasks ### Architecture ### Lookout ] .right-column[ * Automate more labeling on issues and pull requests * Implement GitLab API support ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * We want that other communities and organisations use this as well * many of them use GitLab --- count: false .left-column[ ## VPT ### Automate daily tasks ### Architecture ### Lookout ] .right-column[ * Automate more labeling on issues and pull requests * Implement GitLab API support * Help companies that want to host this on premise for internal repositories ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## VPT ### Automate daily tasks ### Architecture ### Lookout ### Conclusion ] .right-column[ * Vox Pupuli is awesome, please contribute! * We've great tooling to scale module handling * GitHub/GitLab API enables us to automate even more and to focus on code reviewing * Let us know which parts in the communities you would like to see automated * Checkout the current dashboard at [voxpupu.li](https://voxpupu.li) or our docs at [github.com/voxpupuli/vox-pupuli-tasks](https://github.com/voxpupuli/vox-pupuli-tasks#vox-pupuli-tasks---the-webapp-for-community-management) ### Thanks for your attention! ] .footnote[[@Was1NicerDude](https://twitter.com/Was1NicerDude) & [@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * We've some open issues with collected ideas. We need feedback!