class: center, middle, inverseold # Vox Pupuli - Behind every successful open source project
is a vibrant community --- class: center, middle, inverseold # Vox Pupuli - Behind every successful open source project
is a vibrant community ## How to grow an online community to over 210 people managing over 300 projects --- ## $ whoami
* Tim 'bastelfreak' Meusel * Puppet User since 2012 * Merging stuff on [Vox Pupuli](https://voxpupuli.org/) since 2015 * Senior IT Automation Consultant at [betadots](https://betadots.de/) * Puppet Solution Consultant * Vox Pupuli PMC member
??? * who has seen this picture before because I reviewed/merged your pull request? --- class: center, middle, inverse # What is
Puppet? ??? * Who knows Puppet or worked with it? --- .left-column[ ## Puppet ### What? ] .right-column[ * Infrastructure as Code (IaC) Software ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- count: false .left-column[ ## Puppet ### What? ] .right-column[ * Infrastructure as Code (IaC) Software * Brings its own declarative Language, Puppet DSL ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * Alternatives like Salt/Ansible don't, they are mostly YAML --- count: false .left-column[ ## Puppet ### What? ] .right-column[ * Infrastructure as Code (IaC) Software * Brings its own declarative Language, Puppet DSL * Invented/Owned by Puppet Inc (acquired by Perforce) ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- count: false .left-column[ ## Puppet ### What? ] .right-column[ * Infrastructure as Code (IaC) Software * Brings its own declarative Language, Puppet DSL * Invented/Owned by Puppet Inc (acquired by Perforce) * Apache-2.0 license (with CLA) ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## Puppet ### What? ### How? ] .right-column[ example class to manage nginx: ```puppet \# @summary configures nginx in a bad way \# @param content the whole nginx config class nginx ( Sensitive[String[1]] $content, ) { package { 'nginx': ensure => 'installed', } -> file { '/etc/nginx/nginx.conf': ensure => 'file', content => $content, } ~> service { 'nginx': ensure => 'running', enable => true, } } ``` ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * example class of three resources. A resources describes one specific thing on a system --- .left-column[ ## Puppet ### What? ### How? ] .right-column[ * one or multiple classes are organised in a Puppet Module * glorified .tar.gz archive * similar to a Ruby gem or Python package ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- count: false .left-column[ ## Puppet ### What? ### How? ] .right-column[ * one or multiple classes are organised in a Puppet Module * glorified .tar.gz archive * similar to a Ruby gem or Python package * Usually each Puppet Modules lives in its own Git(Hub) repository * A module is focussed on managing a specific software component ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * grouping resources based on software component makes modules exchangeable and composable! --- class: center, middle, inverse # Who uses
Open Source Software? ??? * easy question as a warm up --- class: center, middle, inverse # Who tried to
report a Bug? ??? * Among this group, who wanted to report a bug or provide a patch? --- class: center, middle, inverse # Who uses dead
Open Source Software? ??? * Wer hat während des bugreports gemerkt dass das projekt nur einer person gehört die seit 3 jahren nichts mehr daran gemacht hat? You might guess where this is going --- class: center, middle, inverse # What is this
Vox Pupuli thingy? ??? Now a question I will try to answer for you, what is vox pupuli * Who heard about it before? --- .left-column[ ## Vox Pupuli ### What? ] .right-column[ * Maintain many many Puppet modules ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? Some stats. A group that: * 150 Puppet modules in 2021. 179 *active* modules at the moment * 43 Ruby Gems in 2021, 54 *active* gems at the moment --- count: false .left-column[ ## Vox Pupuli ### What? ] .right-column[ * Maintain many many Puppet modules * And Ruby gems! ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * 150 Puppet modules in 2021. 175 *active* modules at the moment * 43 Ruby Gems in 2021, 54 *active* gems at the moment --- count: false .left-column[ ## Vox Pupuli ### What? ] .right-column[ * Maintain many many Puppet modules * And Ruby gems! * Be helpful and polite to each other ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * We've a code of conduct at least since 2016 and had a single violation * A person wasn't polite to a few others --- count: false .left-column[ ## Vox Pupuli ### What? ] .right-column[ * Maintain many many Puppet modules * And Ruby gems! * Be helpful and polite to each other * Be open-minded to people and technology ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * new people are always welcome and it's easy to participate * usually interact via IRC or via GitHub issues and pull requests * Puppet/Perforce has a slack community. Our slack room is bridged with our IRC channel * technology: example conversation: Hey can I add gentoo support to a module? Or Arch Linux support? * domain specific experts * Any fellow Arch Linux friends here? --- count: false .left-column[ ## Vox Pupuli ### What? ] .right-column[ * Maintain many many Puppet modules * And Ruby gems! * Be helpful and polite to each other * Be open-minded to people and technology * Provide a home for orphaned Puppet modules ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- count: false .left-column[ ## Vox Pupuli ### What? ] .right-column[ * Maintain many many Puppet modules * And Ruby gems! * Be helpful and polite to each other * Be open-minded to people and technology * Provide a home for orphaned Puppet modules * Unite lonely module and tooling authors to a collective ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- count: false .left-column[ ## Vox Pupuli ### What? ] .right-column[ * Maintain many many Puppet modules * And Ruby gems! * Be helpful and polite to each other * Be open-minded to people and technology * Provide a home for orphaned Puppet modules * Unite lonely module and tooling authors to a collective * Ensure continued development for our code ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * We want to work together on modules * together we develop tooling to test our modules --- .left-column[ ## Vox Pupuli ### What? ### Who? ] .right-column[ Members in the Vox Pupuli GitHub Org  ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * 2021: 161 members in the GitHub org with merge access * now: 213 * every dot marks a presentation about or related to vox pupuli * break even point erreicht? macht jetzt jeder cloud und terraform? oder serverless? oder nocode --- .left-column[ ## Vox Pupuli ### What? ### Who? ] .right-column[ * Many git newbies * `git rebase` is hard ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ] .right-column[ * Many git newbies * `git rebase` is hard * Many newcomers to test frameworks * Interested in learing RuboCop/puppet-lint/rspec-puppet/serverspec ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * Those are the tools we use in our CI * talk about them later * CI runs automatically * CI does code annotations * People want to fix/enhance their code because CI feedback is quick and nice --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ] .right-column[ * Many git newbies * `git rebase` is hard * Many newcomers to test frameworks * Interested in learing RuboCop/puppet-lint/rspec-puppet/serverspec * SRE/DevOps/Platform/Systems Engineers in a tiny team * Use Puppet at work and want to use public modules ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * a team so tiny, often a single person --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ] .right-column[ * Many git newbies * `git rebase` is hard * Many newcomers to test frameworks * Interested in learing RuboCop/puppet-lint/rspec-puppet/serverspec * SRE/DevOps/Platform/Systems Engineers in a tiny team * Use Puppet at work and want to use public modules * Consultants that contribute to a few modules for a period of time ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * We provide letter of recognitions or kinda an employment reference --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ] .right-column[ * Maintaining a (successful) FOSS project on your own is hard ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * Who of you maintains a open source project --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ] .right-column[ * Maintaining a (successful) FOSS project on your own is hard * successful implies documentation ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ] .right-column[ * Maintaining a (successful) FOSS project on your own is hard * successful implies documentation * More users → more bugreports and feature requests ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ] .right-column[ * Maintaining a (successful) FOSS project on your own is hard * successful implies documentation * More users → more bugreports and feature requests * People loose interest, lack time, burnout ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * if a single person maintains a project: the more users you have the more likely it is to burn out * remember earlier when I asked about abandoned software? --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ] .right-column[ * Maintaining a (successful) FOSS project on your own is hard * successful implies documentation * More users → more bugreports and feature requests * People loose interest, lack time, burnout * Vox Pupuli wants to prevent this * with a big group of collaborators and efficient tooling ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * if a single person maintains a project: the more users you have the more likely it is to burn out * remember earlier when I asked about abandoned software? --- class: center, middle, inverse # How does
Vox Pupuli work? ??? * now you might as yourself. this sounds amazing, how does it work? Glad you're asking --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[  ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * who worked in a company with a similar complex org chart? * Who liked it? * Who prefers small/flat hierarchies? --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[  ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * there is no real hierarchy * Vox Pupuli is one big group * we work with lazy consensus * If a decision needs to be made and there is no majority for any of the options, PMC will choose * people love to work in such an environment, it enables people --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Style guide and coding best practices are important! ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * what else do people love about vox pupuli? Our styleguide * We are distributed around the world * From the beginning, we were in different timezones and people with different backgrounds --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Style guide and coding best practices are important! * Write down every discussion about it, document it! ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * Often it's possible to implement something in different ways * Or to format the code in different ways * we notice this during code reviews, we use PRs for every change/contribution * if something is unclear, we talk about it and document it afterwards --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Style guide and coding best practices are important! * Write down every discussion about it, document it! * It's okay to update a style guide or revert a decission ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * This is a living document. new collaborators should read it. those people are awesome to spot (my) spelling issues, enhancements, stuff that doesnt make sense * review it for each new puppet version --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Style guide and coding best practices are important! * Write down every discussion about it, document it! * It's okay to update a style guide or revert a decission * Our styleguide: [voxpupuli.org/docs/reviewing_pr](https://voxpupuli.org/docs/reviewing_pr/) ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * If you've a development team within your company, I recommend following this pattern * Write down your guidelines, publish them on the internet, interact with others --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Style guide and coding best practices are important! * Write down every discussion about it, document it! * It's okay to update a style guide or revert a decission * Our styleguide: [voxpupuli.org/docs/reviewing_pr](https://voxpupuli.org/docs/reviewing_pr/) * Over time our guidelines got adopted by many companies and Perforce themselves * It's the defacto standard for the Puppet language ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * code best practice and style guide * Puppet/Perforce also has a styleguide, but it's lacking many details. Ours is an enhancement or addition --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Style guide and coding best practices are important! * Write down every discussion about it, document it! * It's okay to update a style guide or revert a decission * Our styleguide: [voxpupuli.org/docs/reviewing_pr](https://voxpupuli.org/docs/reviewing_pr/) * Over time our guidelines got adopted by many companies and Perforce themself * It's the defacto standard for the Puppet language * A styleguide brings more value if you can enforce it ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * Wouldnt it be nice if we could enforce this somehow? if we could verify if our code looks like the styleguide recommends it? --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Style guide and coding best practices are important! * Write down every discussion about it, document it! * It's okay to update a style guide or revert a decission * Our styleguide: [voxpupuli.org/docs/reviewing_pr](https://voxpupuli.org/docs/reviewing_pr/) * Over time our guidelines got adopted by many companies and Perforce themself * It's the defacto standard for the Puppet language * A styleguide brings more value if you can enforce it * puppet-lint, rubocop, metadata-json-lint ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * linters! * metadata-json-lint for json, rubocop for ruby files, puppet-lint for puppet DSL * puppet-lint can be extended with plugins. one plugin for each specific entry in the styleguide * this makes reviews easier. as a contributor, you don't need to wait for feedback from us. there are tools that can tell you what's wrong. and in most cases how to fix it (autofix). People love that. --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * A CI system is important! * Provide feedback fast, reduce required review time ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * I still fix bugs in other projects and notice that they don't have any tests or linting --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * A CI system is important! * Provide feedback fast, reduce required review time * Use code annotations! ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * GitHub and GitLab support this. A linting/test tool can tell the CI system which line, which character violated a styleguide or broke a test --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Code Annotations (RuboCop)!  ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * example for RuboCop. tells you the line, what kind of violation and a link to documentation * turns out people love that! * this enables people to work on their own most of the time, with a very short feedback loop --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Code Annotations (RuboCop, puppet-lint)!  ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * we have the same feature for puppet-lint * what does it say? missing docs? * Remember when I earlier talked about documentation in a project? * In the puppet ecosystem you can add some inline comments and a tool called puppet-strings can generate documentation * We check during each CI run if the REFERENCE.md is up2date * many languages support it to generate documentation from code+inline docs. if yours does it, use it! * puppet forge will display the REFERENCE.md for each release --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Code Annotations (RuboCop, puppet-lint)!  * Rendered via [puppet-strings](https://www.puppet.com/docs/puppet/latest/puppet_strings.html) at [puppetmodule.info](https://puppetmodule.info/modules) ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * puppetmodule.info --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Code Annotations (RuboCop, puppet-lint, rspec-puppet)!  ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * rspec-puppet is used for unit testing * note the operating system? keep that in mind? --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Code Annotations (RuboCop, puppet-lint, rspec-puppet, Beaker)!  ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * Beaker macht acceptance testing --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * A CI system is important! * A CI system should provide feedback as soon as possible ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * who likes to wait 20 minutes for CI to get feedback? Only people that drink a lot of coffee and need a refill --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * CI Matrix Generator  ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? We implemented this in github actions. * we start from quick checks to slower checks * first validate the code. puppet code, ruby code, if the syntax is valid * the linting and formatting. that's RuboCop/puppet-lint mentioned earlier * then we generate a CI matrix --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * CI Matrix Generator * `jq .requirements[0] metadata.json` ```json { "name": "puppet", "version_requirement": ">= 7.0.0 < 9.0.0" } ``` ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * each puppet module contains a metadata.json * it lists the supported puppet versions * we get each major version and can generate CI jobs for each major version * makes implementing support for newer versions easy. bump metadata.json and watch CI * same pattern works in other languages, like python or ruby projects * dont hardcode this in your CI config. --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * CI Matrix Generator * `jq .requirements[0] metadata.json` ```json { "name": "puppet", "version_requirement": ">= 7.0.0 < 9.0.0" } ``` * `jq .operatingsystem_support[0] metadata.json` ```json { "operatingsystem": "Debian", "operatingsystemrelease": [ "11", "12" ] } ``` ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * We have a tool called beaker to spin up VMs/docker instances * generate one job per OS version per puppet version * remember earlier when we talked about being open to new technology? someone wanting to add support for a new operating system? add it to metadata.json and you get a new CI job --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * CI Matrix Generator * Documentation: [github.com/voxpupuli/gha-puppet](https://github.com/voxpupuli/gha-puppet#puppet-github-actions) ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? As mentioned, documentation is important, the whole setup is FOSS and runs on GitHub actions, can be ported to gitlab --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * CI Matrix Generator * Documentation: [github.com/voxpupuli/gha-puppet](https://github.com/voxpupuli/gha-puppet#puppet-github-actions) * Reuseable GitHub Workflow ```yaml --- name: CI on: pull_request concurrency: group: ${{ github.ref_name }} cancel-in-progress: true jobs: puppet: name: Puppet uses: voxpupuli/gha-puppet/.github/workflows/beaker.yml@v3 ``` ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? just in case you develop modules on github, you can reuse our workflow --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * CI Matrix Generator * Documentation: [github.com/voxpupuli/gha-puppet](https://github.com/voxpupuli/gha-puppet#puppet-github-actions) * Reuseable GitHub Workflow * Everything can be run locally: [voxpupuli.org/docs/how_to_run_tests](https://voxpupuli.org/docs/how_to_run_tests/) ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * CI Matrix Generator * Documentation: [github.com/voxpupuli/gha-puppet](https://github.com/voxpupuli/gha-puppet#puppet-github-actions) * Reuseable GitHub Workflow * Everything can be run locally: [voxpupuli.org/docs/how_to_run_tests](https://voxpupuli.org/docs/how_to_run_tests/) ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? Thats a github feature. when you open a PR and the file is present, github will tell you about it --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * CI Matrix Generator * Documentation: [github.com/voxpupuli/gha-puppet](https://github.com/voxpupuli/gha-puppet#puppet-github-actions) * Reuseable GitHub Workflow * Everything can be run locally: [voxpupuli.org/docs/how_to_run_tests](https://voxpupuli.org/docs/how_to_run_tests/) * Add a CONTRIBUTING.md to a module ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? Thats a github feature. when you open a PR and the file is present, github will tell you about it --- .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Each project has some boilerplate stuff * Rakefile, directory structure, CONTRIBUTING.md ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Each project has some boilerplate stuff * Rakefile, directory structure, CONTRIBUTING.md * modulesync was developed by Puppet, moved to Vox Pupuli * It takes a config file + templates * Syncs it into every module git repository * Source Code: [github.com/voxpupuli/modulesync](https://github.com/voxpupuli/modulesync#modulesync) ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * this is not puppet-specific, it can be used for every group of git repos with similar boilerplate code * it can automatically create GitLab/GitHub/GitHub Enterprise PRs, or just push branches * distributed as ruby gem --- count: false .left-column[ ## Vox Pupuli ### What? ### Who? ### Why? ### How? ] .right-column[ * Our config repo: [github.com/voxpupuli/modulesync_config](https://github.com/voxpupuli/modulesync_config#modulesync-configs)  ] --- class: center, middle, inverse # The
Conclusion --- .left-column[ ## Vox Pupuli ### Conclusion ] .right-column[ * Document how your team works ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] --- count: false .left-column[ ## Vox Pupuli ### Conclusion ] .right-column[ * Document how your team works * Try to develop publicly, even corporate code ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] --- count: false .left-column[ ## Vox Pupuli ### Conclusion ] .right-column[ * Document how your team works * Try to develop publicly, even corporate code * Document your style guide ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * habt überhaupt einen stylgeguide * dokumentiert warum ihr euch für style X entschieden habt * bleibt möglichst nah am upstream styleguide * dokumentiert wenn ihr davon abweicht --- count: false .left-column[ ## Vox Pupuli ### Conclusion ] .right-column[ * Document how your team works * Try to develop publicly, even corporate code * Document your style guide * Document your projects ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- count: false .left-column[ ## Vox Pupuli ### Conclusion ] .right-column[ * Document how your team works * Try to develop publicly, even corporate code * Document your style guide * Document your projects * Try to reduce boilerplate code ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * Ist die dokumentation gut genug das sich ein neuer mitarbeiter eigenständig einarbeiten kann? * Sind externe user, die nicht bei euch arbeiten, in der lage die doku zu finden und zu verstehen? --- count: false .left-column[ ## Vox Pupuli ### Conclusion ] .right-column[ * Document how your team works * Try to develop publicly, even corporate code * Document your style guide * Document your projects * Try to reduce boilerplate code * Manage boilerplate code in a central place ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? --- .left-column[ ## Vox Pupuli ### Conclusion ### Contact ] .right-column[ * IRC: [Libera.Chat/#voxpupuli](https://web.libera.chat/?#voxpupuli) * Mailinglist: [voxpupuli@groups.io](mailto:voxpupuli@groups.io) * Feedback: [tim@bastelfreak.de](mailto:tim@bastelfreak.de) * Slideset and more talks: [github.com/bastelfreak/talks](https://github.com/bastelfreak/talks) * Support Vox Pupuli via [GitHub sponsors](https://github.com/sponsors/voxpupuli) or [OpenCollective](https://opencollective.com/vox-pupuli/) ### Thanks for your attention! ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? * Danke betadots fürs sponsoring * wir stellen ein * supported vox pupuli --- .left-column[ ## Vox Pupuli ### Conclusion ### Contact ### Link Collection ] .right-column[ * Website: [voxpupuli.org/docs/](https://voxpupuli.org/docs/) * CI Setup: [github.com/voxpupuli/gha-puppet](https://github.com/voxpupuli/gha-puppet#puppet-github-actions) * Unit Tests: [github.com/voxpupuli/voxpupuli-test](https://github.com/voxpupuli/voxpupuli-test#voxpupuli-test-gem) * Acceptance Tests: [github.com/voxpupuli/voxpupuli-acceptance](https://github.com/voxpupuli/voxpupuli-acceptance#voxpupuli-acceptance-gem) * Release Tooling: [github.com/voxpupuli/voxpupuli-release](https://github.com/voxpupuli/voxpupuli-release#vox-pupuli-release-gem) * modulesync_config: [github.com/voxpupuli/modulesync_config](https://github.com/voxpupuli/modulesync_config#modulesync-configs) ]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)] ??? ??? CI setup --- count: false .left-column[ ## Vox Pupuli ] .right-column[
]
.footnote[[@bastelsblog](https://twitter.com/bastelsblog) for [@voxpupuliorg](https://twitter.com/voxpupuliorg)]