A place to cache linked articles (think custom and personal wayback machine)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 34KB

  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang=fr>
  4. <!-- Has to be within the first 1024 bytes, hence before the <title>
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset=utf-8>
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name=viewport content="width=device-width,minimum-scale=1,initial-scale=1,shrink-to-fit=no">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Five best practices in open source: external engagement (archive) — David Larlet</title>
  13. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  14. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons/apple-touch-icon.png">
  15. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons/favicon-32x32.png">
  16. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons/favicon-16x16.png">
  17. <link rel="manifest" href="/manifest.json">
  18. <link rel="mask-icon" href="/static/david/icons/safari-pinned-tab.svg" color="#5bbad5">
  19. <link rel="shortcut icon" href="/static/david/icons/favicon.ico">
  20. <meta name="apple-mobile-web-app-title" content="David Larlet">
  21. <meta name="application-name" content="David Larlet">
  22. <meta name="msapplication-TileColor" content="#da532c">
  23. <meta name="msapplication-config" content="/static/david/icons/browserconfig.xml">
  24. <meta name="theme-color" content="#f0f0ea">
  25. <!-- That good ol' feed, subscribe :p. -->
  26. <link rel=alternate type="application/atom+xml" title=Feed href="/david/log/">
  27. <meta name="robots" content="noindex, nofollow">
  28. <meta content="origin-when-cross-origin" name="referrer">
  29. <!-- Canonical URL for SEO purposes -->
  30. <link rel="canonical" href="http://ben.balter.com/2015/03/17/open-source-best-practices-external-engagement/">
  31. <style>
  32. /* http://meyerweb.com/eric/tools/css/reset/ */
  33. html, body, div, span,
  34. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  35. a, abbr, address, big, cite, code,
  36. del, dfn, em, img, ins,
  37. small, strike, strong, tt, var,
  38. dl, dt, dd, ol, ul, li,
  39. fieldset, form, label, legend,
  40. table, caption, tbody, tfoot, thead, tr, th, td,
  41. article, aside, canvas, details, embed,
  42. figure, figcaption, footer, header, hgroup,
  43. menu, nav, output, ruby, section, summary,
  44. time, mark, audio, video {
  45. margin: 0;
  46. padding: 0;
  47. border: 0;
  48. font-size: 100%;
  49. font: inherit;
  50. vertical-align: baseline;
  51. }
  52. /* HTML5 display-role reset for older browsers */
  53. article, aside, details, figcaption, figure,
  54. footer, header, hgroup, menu, nav, section { display: block; }
  55. body { line-height: 1; }
  56. blockquote, q { quotes: none; }
  57. blockquote:before, blockquote:after,
  58. q:before, q:after {
  59. content: '';
  60. content: none;
  61. }
  62. table {
  63. border-collapse: collapse;
  64. border-spacing: 0;
  65. }
  66. /* http://practicaltypography.com/equity.html */
  67. /* https://calendar.perfplanet.com/2016/no-font-face-bulletproof-syntax/ */
  68. /* https://www.filamentgroup.com/lab/js-web-fonts.html */
  69. @font-face {
  70. font-family: 'EquityTextB';
  71. src: url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff2') format('woff2'),
  72. url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff') format('woff');
  73. font-weight: 300;
  74. font-style: normal;
  75. font-display: swap;
  76. }
  77. @font-face {
  78. font-family: 'EquityTextB';
  79. src: url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff2') format('woff2'),
  80. url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff') format('woff');
  81. font-weight: 300;
  82. font-style: italic;
  83. font-display: swap;
  84. }
  85. @font-face {
  86. font-family: 'EquityTextB';
  87. src: url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff2') format('woff2'),
  88. url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff') format('woff');
  89. font-weight: 700;
  90. font-style: normal;
  91. font-display: swap;
  92. }
  93. @font-face {
  94. font-family: 'ConcourseT3';
  95. src: url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff2') format('woff2'),
  96. url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff') format('woff');
  97. font-weight: 300;
  98. font-style: normal;
  99. font-display: swap;
  100. }
  101. /* http://practice.typekit.com/lesson/caring-about-opentype-features/ */
  102. body {
  103. /* http://www.cssfontstack.com/ Palatino 99% Win 86% Mac */
  104. font-family: "EquityTextB", Palatino, serif;
  105. background-color: #f0f0ea;
  106. color: #07486c;
  107. font-kerning: normal;
  108. -moz-osx-font-smoothing: grayscale;
  109. -webkit-font-smoothing: subpixel-antialiased;
  110. text-rendering: optimizeLegibility;
  111. font-variant-ligatures: common-ligatures contextual;
  112. font-feature-settings: "kern", "liga", "clig", "calt";
  113. }
  114. pre, code, kbd, samp, var, tt {
  115. font-family: 'TriplicateT4c', monospace;
  116. }
  117. em {
  118. font-style: italic;
  119. color: #323a45;
  120. }
  121. strong {
  122. font-weight: bold;
  123. color: black;
  124. }
  125. nav {
  126. background-color: #323a45;
  127. color: #f0f0ea;
  128. display: flex;
  129. justify-content: space-around;
  130. padding: 1rem .5rem;
  131. }
  132. nav:last-child {
  133. border-bottom: 1vh solid #2d7474;
  134. }
  135. nav a {
  136. color: #f0f0ea;
  137. }
  138. nav abbr {
  139. border-bottom: 1px dotted white;
  140. }
  141. h1 {
  142. border-top: 1vh solid #2d7474;
  143. border-bottom: .2vh dotted #2d7474;
  144. background-color: #e3e1e1;
  145. color: #323a45;
  146. text-align: center;
  147. padding: 5rem 0 4rem 0;
  148. width: 100%;
  149. font-family: 'ConcourseT3';
  150. display: flex;
  151. flex-direction: column;
  152. }
  153. h1.single {
  154. padding-bottom: 10rem;
  155. }
  156. h1 span {
  157. position: absolute;
  158. top: 1vh;
  159. left: 20%;
  160. line-height: 0;
  161. }
  162. h1 span a {
  163. line-height: 1.7;
  164. padding: 1rem 1.2rem .6rem 1.2rem;
  165. border-radius: 0 0 6% 6%;
  166. background: #2d7474;
  167. font-size: 1.3rem;
  168. color: white;
  169. text-decoration: none;
  170. }
  171. h2 {
  172. margin: 4rem 0 1rem;
  173. border-top: .2vh solid #2d7474;
  174. padding-top: 1vh;
  175. }
  176. h3 {
  177. text-align: center;
  178. margin: 3rem 0 .75em;
  179. }
  180. hr {
  181. height: .4rem;
  182. width: .4rem;
  183. border-radius: .4rem;
  184. background: #07486c;
  185. margin: 2.5rem auto;
  186. }
  187. time {
  188. display: bloc;
  189. margin-left: 0 !important;
  190. }
  191. ul, ol {
  192. margin: 2rem;
  193. }
  194. ul {
  195. list-style-type: square;
  196. }
  197. a {
  198. text-decoration-skip-ink: auto;
  199. text-decoration-thickness: 0.05em;
  200. text-underline-offset: 0.09em;
  201. }
  202. article {
  203. max-width: 50rem;
  204. display: flex;
  205. flex-direction: column;
  206. margin: 2rem auto;
  207. }
  208. article.single {
  209. border-top: .2vh dotted #2d7474;
  210. margin: -6rem auto 1rem auto;
  211. background: #f0f0ea;
  212. padding: 2rem;
  213. }
  214. article p:last-child {
  215. margin-bottom: 1rem;
  216. }
  217. p {
  218. padding: 0 .5rem;
  219. margin-left: 3rem;
  220. }
  221. p + p,
  222. figure + p {
  223. margin-top: 2rem;
  224. }
  225. blockquote {
  226. background-color: #e3e1e1;
  227. border-left: .5vw solid #2d7474;
  228. display: flex;
  229. flex-direction: column;
  230. align-items: center;
  231. padding: 1rem;
  232. margin: 1.5rem;
  233. }
  234. blockquote cite {
  235. font-style: italic;
  236. }
  237. blockquote p {
  238. margin-left: 0;
  239. }
  240. figure {
  241. border-top: .2vh solid #2d7474;
  242. background-color: #e3e1e1;
  243. text-align: center;
  244. padding: 1.5rem 0;
  245. margin: 1rem 0 0;
  246. font-size: 1.5rem;
  247. width: 100%;
  248. }
  249. figure img {
  250. max-width: 250px;
  251. max-height: 250px;
  252. border: .5vw solid #323a45;
  253. padding: 1px;
  254. }
  255. figcaption {
  256. padding: 1rem;
  257. line-height: 1.4;
  258. }
  259. aside {
  260. display: flex;
  261. flex-direction: column;
  262. background-color: #e3e1e1;
  263. padding: 1rem 0;
  264. border-bottom: .2vh solid #07486c;
  265. }
  266. aside p {
  267. max-width: 50rem;
  268. margin: 0 auto;
  269. }
  270. /* https://fvsch.com/code/css-locks/ */
  271. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  272. font-size: 1rem;
  273. line-height: calc( 1.5em + 0.2 * 1rem );
  274. }
  275. h1 {
  276. font-size: 1.9rem;
  277. line-height: calc( 1.2em + 0.2 * 1rem );
  278. }
  279. h2 {
  280. font-size: 1.6rem;
  281. line-height: calc( 1.3em + 0.2 * 1rem );
  282. }
  283. h3 {
  284. font-size: 1.35rem;
  285. line-height: calc( 1.4em + 0.2 * 1rem );
  286. }
  287. @media (min-width: 20em) {
  288. /* The (100vw - 20rem) / (50 - 20) part
  289. resolves to 0-1rem, depending on the
  290. viewport width (between 20em and 50em). */
  291. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  292. font-size: calc( 1rem + .6 * (100vw - 20rem) / (50 - 20) );
  293. line-height: calc( 1.5em + 0.2 * (100vw - 50rem) / (20 - 50) );
  294. margin-left: 0;
  295. }
  296. h1 {
  297. font-size: calc( 1.9rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  298. line-height: calc( 1.2em + 0.2 * (100vw - 50rem) / (20 - 50) );
  299. }
  300. h2 {
  301. font-size: calc( 1.5rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  302. line-height: calc( 1.3em + 0.2 * (100vw - 50rem) / (20 - 50) );
  303. }
  304. h3 {
  305. font-size: calc( 1.35rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  306. line-height: calc( 1.4em + 0.2 * (100vw - 50rem) / (20 - 50) );
  307. }
  308. }
  309. @media (min-width: 50em) {
  310. /* The right part of the addition *must* be a
  311. rem value. In this example we *could* change
  312. the whole declaration to font-size:2.5rem,
  313. but if our baseline value was not expressed
  314. in rem we would have to use calc. */
  315. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  316. font-size: calc( 1rem + .6 * 1rem );
  317. line-height: 1.5em;
  318. }
  319. p, li, pre, details {
  320. margin-left: 3rem;
  321. }
  322. h1 {
  323. font-size: calc( 1.9rem + 1.5 * 1rem );
  324. line-height: 1.2em;
  325. }
  326. h2 {
  327. font-size: calc( 1.5rem + 1.5 * 1rem );
  328. line-height: 1.3em;
  329. }
  330. h3 {
  331. font-size: calc( 1.35rem + 1.5 * 1rem );
  332. line-height: 1.4em;
  333. }
  334. figure img {
  335. max-width: 500px;
  336. max-height: 500px;
  337. }
  338. }
  339. figure.unsquared {
  340. margin-bottom: 1.5rem;
  341. }
  342. figure.unsquared img {
  343. height: inherit;
  344. }
  345. @media print {
  346. body { font-size: 100%; }
  347. a:after { content: " (" attr(href) ")"; }
  348. a, a:link, a:visited, a:after {
  349. text-decoration: underline;
  350. text-shadow: none !important;
  351. background-image: none !important;
  352. background: white;
  353. color: black;
  354. }
  355. abbr[title] { border-bottom: 0; }
  356. abbr[title]:after { content: " (" attr(title) ")"; }
  357. img { page-break-inside: avoid; }
  358. @page { margin: 2cm .5cm; }
  359. h1, h2, h3 { page-break-after: avoid; }
  360. p3 { orphans: 3; widows: 3; }
  361. img {
  362. max-width: 250px !important;
  363. max-height: 250px !important;
  364. }
  365. nav, aside { display: none; }
  366. }
  367. ul.with_columns {
  368. column-count: 1;
  369. }
  370. @media (min-width: 20em) {
  371. ul.with_columns {
  372. column-count: 2;
  373. }
  374. }
  375. @media (min-width: 50em) {
  376. ul.with_columns {
  377. column-count: 3;
  378. }
  379. }
  380. ul.with_two_columns {
  381. column-count: 1;
  382. }
  383. @media (min-width: 20em) {
  384. ul.with_two_columns {
  385. column-count: 1;
  386. }
  387. }
  388. @media (min-width: 50em) {
  389. ul.with_two_columns {
  390. column-count: 2;
  391. }
  392. }
  393. .gallery {
  394. display: flex;
  395. flex-wrap: wrap;
  396. justify-content: space-around;
  397. }
  398. .gallery figure img {
  399. margin-left: 1rem;
  400. margin-right: 1rem;
  401. }
  402. .gallery figure figcaption {
  403. font-family: 'ConcourseT3'
  404. }
  405. footer {
  406. font-family: 'ConcourseT3';
  407. display: flex;
  408. flex-direction: column;
  409. border-top: 3px solid white;
  410. padding: 4rem 0;
  411. background-color: #07486c;
  412. color: white;
  413. }
  414. footer > * {
  415. max-width: 50rem;
  416. margin: 0 auto;
  417. }
  418. footer a {
  419. color: #f1c40f;
  420. }
  421. footer .avatar {
  422. width: 200px;
  423. height: 200px;
  424. border-radius: 50%;
  425. float: left;
  426. -webkit-shape-outside: circle();
  427. shape-outside: circle();
  428. margin-right: 2rem;
  429. padding: 2px 5px 5px 2px;
  430. background: white;
  431. border-left: 1px solid #f1c40f;
  432. border-top: 1px solid #f1c40f;
  433. border-right: 5px solid #f1c40f;
  434. border-bottom: 5px solid #f1c40f;
  435. }
  436. </style>
  437. <h1>
  438. <span><a id="jumper" href="#jumpto" title="Un peu perdu ?">?</a></span>
  439. Five best practices in open source: external engagement (archive)
  440. <time>Pour la pérennité des contenus liés. Non-indexé, retrait sur simple email.</time>
  441. </h1>
  442. <section>
  443. <article>
  444. <h3><a href="http://ben.balter.com/2015/03/17/open-source-best-practices-external-engagement/">Source originale du contenu</a></h3>
  445. <p>When it comes to open source, simply publishing code isn’t enough. Open source is about fostering communities around shared challenges. Sure, you’ll want to <a href="http://ben.balter.com/2015/03/08/open-source-best-practices-internal-collaboration/">fine tune your internal collaboration workflows</a>, but at its core, open source is about proactively engaging external developers and supporting their ability to contribute. You can have open source without executive oversight. You can have open source without policy guidance. You can even have open source without large organizations. But you can’t have open source without open source developers and you certainly can’t have open source without open source code.</p>
  446. <p>Working regularly with government agencies to help ensure their first (or second) step into the open source world is a successful one, here are five best practices for pursuing open source in government (or any large organization for that matter):</p>
  447. <h3 id="expand-your-definition-of-stakeholders">1. Expand your definition of stakeholders</h3>
  448. <p>Going in to your first open source project, you’ll likely have a narrow definition of stakeholders. You’ve probably accounted for open source developers, internal business owners or subject matter experts, and possibly the press. Open source communities are made out of many more types of stakeholders, on both sides of the firewall. Put a different way, <a href="http://ben.balter.com/2013/08/11/everyone-contributes/">everyone contributes</a>.</p>
  449. <p>Here’s a short list of personas that likely already care about your project, our would care, if properly engaged:</p>
  450. <ul>
  451. <li>Non-technical, non-user stakeholders</li>
  452. <li>Potential users</li>
  453. <li>Veteran (or curious) users</li>
  454. <li>Subject matter experts (accessibility, content, i18n)</li>
  455. <li>Technical users</li>
  456. <li>Active developers</li>
  457. <li>Potential developers</li>
  458. </ul>
  459. <p>Even before you hit publish, there’s lots of ways to seed your project’s ecosystem with different types of contributors, technical and otherwise. Here’s a few ways they might contribute:</p>
  460. <ul>
  461. <li>Kick the tires, does the thing even work? Does it do what it says it does?</li>
  462. <li>Answer the question “what features would you love to see?”</li>
  463. <li>Flesh out documentation, ask questions, note where documentation is lacking</li>
  464. <li>Community evangelism, speak, teach, and spread your love for the project</li>
  465. <li>Submit new questions to the project’s Q&amp;A forums, or take a stab at an answer or two</li>
  466. <li>Host a genius bar at the next local meetup</li>
  467. <li>Translate the project into a different language</li>
  468. <li>Give feedback on proposed bug fixes and features, propose new ones</li>
  469. <li>Recruit new developers, help junior developers grow into the project</li>
  470. </ul>
  471. <p>In traditional government workflows, many of these functions happen by necessity, but artifacts, if they exist, are invisible to the open source community. Before you seek to engage external stakeholders, shift internal stakeholders off traditional workflows, and have them begin using the same tools you’d use to engage external stakeholders. Have a feature request? Open an issue. Want to review the docuemntation? Here’s a link to the public facing README.</p>
  472. <p>If you do it right, by the time you’re ready to engage the external community, you’ll be a pro, having already used the same tools to engage your internal community, which can now be placed on equal footing as external stakeholders. Put another way, your goal should be to support one large community, not two necessary unequal ones.</p>
  473. <h3 id="be-the-hub-encourage-spokes">2. Be the hub, encourage spokes</h3>
  474. <p>As the maintainer of an open source project, you should think of your role as being the host of the internet’s most boring cocktail party. You are responsible for extending invitations to a diverse list of party goers, providing drinks and snacks, and as attendees arrive one-by-one, taking their coat and providing introductions to one another.</p>
  475. <p>Open source is no different. You must invite contributors, provide them with the necessary tools to collaborate (both social and technical), and to float from conversation to conversation, connecting subject matter and technical experts, and smoothing over any potential disagreements among guests before they even arise.</p>
  476. <p>You can’t be a host, however, if guests are only allowed to talk directly to you. That wouldn’t be much of a party, and in the case of open source, wouldn’t foster much of a community. Yet that’s exactly how most open source efforts are initially structured, by instructing potential contributors to email <code>anonymous-inbox@agency.gov</code> as the sole “official” point of contact.</p>
  477. <p>Instead, minimize one-to-one interactions. There’s absolutely no way for you to scale. The types of questions and feedback you receive are going to be common to one another. <em>Is this column month-day-year or year-month-day?</em> <em>What unit is this represented in?</em>. Engaging developers via email logically necessitates that you’re going to be answering the same question multiple times, and will be engineering a system with a single point of failure: yourself. As we say in web development, non-blocking is better than blocking.</p>
  478. <p><a href="http://ben.balter.com/2014/10/07/expose-process-through-urls/">That means that every answer to every question should have a URL</a> (and a human name and face). As a rule, second time I’m asked a question via email, I always wait until I can reply with a URL, and if it’s a question I know others are going to have, even earlier than that. Ideally, you should only have to answer a question once, or even better, never, if the community can for you. When the second user encounters the same problem, they can search and get connected with the first. Better yet, by the time it’s happened a third time, it’s a documented problem, and a member of the community can propose an update to the documentation. This isn’t hypothetical, this happens every day in open source.</p>
  479. <p>In practicality, that means standing up public, linkable forums for stakeholders to ask questions and submit feedback, to engage with one another, and for you to support the community. Communities are created by relationships between humans — humans with names and faces — not between humans and a shared inbox or anonymous organization account. If all that’s locked away in a shared inbox or behind a corporate logo, if you hold a monopoly on the ability to communicate and funnel it through a single, tightly controlled access point, well, then, nobody’s going to want to come to your party.</p>
  480. <h3 id="minimize-friction">3. Minimize Friction</h3>
  481. <p>At GitHub, we measure workflows in terms of <a href="http://ben.balter.com/2013/08/11/friction/">friction</a>. You can define friction as the time it takes for a potential contributor to go from <em>“I want to contribute”</em> to <em>“I have contributed”</em>. When contributions are on a volunteer basis, minimizing friction is essential to encouraging first time contributors and to turn those first-time contributors into long-term collaborators.</p>
  482. <p>Think about it this way. Lets say I find a typo in your app. I need to make what is literally a single character change. The actually change itself should take less than thirty seconds. But what do I have to do to make that change? I’ll need to figure out the project dependencies and install them, bootstrap a local development environment, make my change, set up the test suite, run tests, and then figure out how to contribute my change back. That 30 seconds change just became a day long process and when friction is disproportionate to the time it takes to do the thing I set out to do, I’m simply not going to contribute.</p>
  483. <p>If a maintainer spends a few hours at the onset improving documentation and scripting common tasks, even if it only shaves a few seconds of contributor friction, those hours the maintainer spends will be well justified in the long run, when you multiply those seconds by the hundreds of developers that may contribute across the project’s lifetime, and the hundred more than would otherwise be turned away without it.</p>
  484. <p>In practice, that means walking through the contribution flow from discovery to merge and deployment, and anticipating the potential contributor’s needs at each step. How do I find the source code? Am I familiar with this language or platform? Where’s the documentation? Have I seen this license before, or do I need to hire a lawyer to know if I can contribute? What are the local system requirements? How do I bootstrap those dependencies? Tests? Once I’ve made my change, what’s the workflow for submitting an improvement? How long should I expect to wait on feedback? How long will it take to get merged so I can go work on the next thing?</p>
  485. <p>A lot of that comes down to contributor-friendly documentation (read: not internal policy), but a sane workflow (e.g., merging pull requests as they come in, not in a standing meeting on the 2nd Tuesday of the month) and some simple tooling can go a long way. At GitHub we have what we call culture tools, meaning I can jump into any project and know how to set things up and submit my proposed fix without reading a single line of documentation. <a href="https://github.com/parkr" class="user-mention">@parkr</a> expanded on that idea with what he calls <a href="https://byparker.com/blog/2015/language-agnostic-interfaces-for-software-development/" data-proofer-ignore="true">“Language-Agnostic Interfaces for Software Development”</a>. Whatever you call it, running <code>script/bootstrap</code> is a heck of a lot easier than spending a few hours learning how some random package manager works.</p>
  486. <h3 id="decentralize-governance">4. Decentralize governance</h3>
  487. <p>Successful open source is all about decentralization and informality, two things large organizations are traditionally terrible at. <a href="http://ben.balter.com/2014/08/03/why-isnt-all-government-software-open-source/">Think about what most large organizations optimize for</a>: meetings, in-house email, strict hierarchy, and tightly held process. In the world of open source, you don’t hold a meeting to merge a pull request. Email is foregone and process is exposed through public discussions. Heck, you don’t even need to be in the office or wearing a suit to comment on an issue. In order to be successful, and the step most large organizations overlook, is that to participate, you need to be a member of the community, not you the organization, but you the human. Open source developers can tell the difference between someone who is “one of them” and “gets it”, and someone who drops in once or week to communicate already-made decisions or follows a telemarketing-like support script when interacting with contributors. Put another way, no matter how much you water it, astroturf will never grow.</p>
  488. <p>When the White House merges a pull request, it’s done by a developer familiar with the project. The CIO doesn’t bring a laptop into the situation room and ask the President to sign off on the changes. That’d be crazy. The president isn’t a software developer, and the people in that room presumably have much better things to do. Yet more often than not, participating in the open source community is seen bureaucratically as public engagement, and thus, must be funneled through a public affairs office or similar committee-like blocking experience.</p>
  489. <p>Instead, push responsibilities to as close to the edge as possible. There’s a lot of different ways to think about community engagement, but essentially, there are three big buckets:</p>
  490. <ul>
  491. <li>
  492. <p><strong>Community stewardship</strong> - Day-to-day community engagement is going to require responding to issues and providing support. The questions may be technical, but more often than not, this role is best served by a fellow, intern, or other member of the open source community, that knows the lay of the land and has managed an open source project before, even if at a smaller (or personal) scale, and can empower others within your organization to do the same. Think of them as your open-source sherpa.</p>
  493. </li>
  494. <li>
  495. <p><strong>Code review-ship</strong> - Beyond general engagement, day-to-day project management will require regular, in-depth code review, providing feedback to developers, and generally working with contributors to enforce the project’s style and goals. This should be a technical person familiar with the project, whether an external contractor, a community member, or employee it doesn’t matter, as long as they’re able to understand the technical issues involved and move proposed changes forward at their own pace. This can be the same person who engages the community, but doesn’t need to be.</p>
  496. </li>
  497. <li>
  498. <p><strong>Leadership</strong> - Last, you’ll want someone to serve in a role the open source community would most often call “lead developer”. There can be multiple lead developers, and those developers can be the ones to provide early code review and feedback, but again, it’s important that they have a firm grasp of the technical issues at play. They’ll be responsible for accepting or rejecting pull requests on behalf of the project, long-term planning, working with the community to establish project roadmaps, coordinating releases, etc.</p>
  499. </li>
  500. </ul>
  501. <p>All of these roles of very different from writing a blog post or composing a Tweet and require a certain degree of speed, flexibility, and technical acumen. The only way the project is going to be successful is by decentralizing project governance to those most closely involved with the project. Obviously matters of policy as well as large, project-defining decisions should include non-technical stakeholders, but just because a code comment is public, doesn’t mean day-to-day maintenance should be the purview of a public affairs office or committee that maintains a standing meeting. Given the pace of open source software development, it’s simply not practical. Open source is about collaboration between humans, not between humans and your entire organization.</p>
  502. <h3 id="encourage-contributors">5. Encourage contributors</h3>
  503. <p>In open source, the right to contribute is assumed. In fact, if you don’t want contributors, if a project is simply published or if a project has reached end of life and is no longer maintained, you must explicitly disclaim that you are <em>not</em> accepting contributions, yet in the world of government and corporate open source, that’s sadly not always the case.</p>
  504. <p>I’ve personally contributed to open source projects maintained by government and other large organizations only to see my code languish as an open pull request, either because the bureaucratic process to review internally was to strict, because they had nobody empowered internally to review and approve the change, or because the code was intentionally only disclosed, and <a href="http://ben.balter.com/2014/09/29/source-disclosed-%E2%89%A0-open-source/">not really open source</a>, but not properly documented. In any case, many developers are left with a bad taste in their mouth from prior experience, and are skeptical of projects run by large organizations.</p>
  505. <p>As a result, to be successful, you’ll want to explicitly let developers know that you’re not only capable of accepting contributions at the pace that they’d expect, but that you <em>want</em> them to contribute. Practically, that comes in a few different forms:</p>
  506. <ul>
  507. <li>
  508. <p><strong>In advance</strong> - Include a phase like “we encourage you to contribute” in the project’s documentation, along with instructions on how to do so. Fork, create a descriptively named feature branch and submit a pull request? Great. Beyond workflow, these instructions should include what to expect from the project maintainers, and the technical requirements to run the projects locally. You’ll want to assume this is the contributor’s first time contributing, because likely it is.</p>
  509. </li>
  510. <li>
  511. <p><strong>Daily</strong> - You must provide constructive support, praise, and feedback with <em>every</em> contribution. Mentor first-time or junior contributors until they’re at the point where they can mentor others. If something doesn’t conform to your standards, hold their digital hand and help them fix it. Most importantly, always express gratitude when merging or commenting. An emoji thank you from the White House or well-known brand can go a long way to guaranteeing the contributor will submit their second (and third) pull request.</p>
  512. </li>
  513. <li>
  514. <p><strong>Going forward</strong> - While not vital on day one, automated testing will go a long way to give potential contributors the confidence to know that their contribution didn’t break anything, and will give project maintainers the confidence to merge it expeditiously. With GitHub and a service like Travis CI, contributors can get early feedback on pull request, simply by submitting a pull request, and all without the project maintainers reading a single line of code. Continuous integration will not only ensure software quality, but can be used to enforce project norms around documentation, style, or other things your organization cares about, in a friendly, self-help way. Ensure you’re not a blocker.</p>
  515. </li>
  516. </ul>
  517. <p>There’s a world of difference between uploading a zip file to an FTP server and open source. Open source is about fostering communities around shared challenges, and as the maintainer of an open source project, that responsibility falls squarely on your shoulders. To be successful, simply publishing code isn’t enough. Go out of your way to encourage, praise, and support each contributor and each contribution as if the project’s success depended on it, because in reality, it does.</p>
  518. <p><strong><em>This post is part of a series on best practices in open source. You may also be interested in <a href="http://ben.balter.com/2015/03/08/open-source-best-practices-internal-collaboration/">Five best practices in open source: internal collaboration</a>.</em></strong></p>
  519. </article>
  520. </section>
  521. <nav id="jumpto">
  522. <p>
  523. <a href="/david/blog/">Accueil du blog</a> |
  524. <a href="http://ben.balter.com/2015/03/17/open-source-best-practices-external-engagement/">Source originale</a> |
  525. <a href="/david/stream/2019/">Accueil du flux</a>
  526. </p>
  527. </nav>
  528. <footer>
  529. <div>
  530. <img src="/static/david/david-larlet-avatar.jpg" loading="lazy" class="avatar" width="200" height="200">
  531. <p>
  532. Bonjour/Hi!
  533. Je suis <a href="/david/" title="Profil public">David&nbsp;Larlet</a>, je vis actuellement à Montréal et j’alimente cet espace depuis 15 ans. <br>
  534. Si tu as apprécié cette lecture, n’hésite pas à poursuivre ton exploration. Par exemple via les <a href="/david/blog/" title="Expériences bienveillantes">réflexions bimestrielles</a>, la <a href="/david/stream/2019/" title="Pensées (dés)articulées">veille hebdomadaire</a> ou en t’abonnant au <a href="/david/log/" title="S’abonner aux publications via RSS">flux RSS</a> (<a href="/david/blog/2019/flux-rss/" title="Tiens c’est quoi un flux RSS ?">so 2005</a>).
  535. </p>
  536. <p>
  537. Je m’intéresse à la place que je peux avoir dans ce monde. En tant qu’humain, en tant que membre d’une famille et en tant qu’associé d’une coopérative. De temps en temps, je fais aussi des <a href="https://github.com/davidbgk" title="Principalement sur Github mais aussi ailleurs">trucs techniques</a>. Et encore plus rarement, <a href="/david/talks/" title="En ce moment je laisse plutôt la place aux autres">j’en parle</a>.
  538. </p>
  539. <p>
  540. Voici quelques articles choisis :
  541. <a href="/david/blog/2019/faire-equipe/" title="Accéder à l’article complet">Faire équipe</a>,
  542. <a href="/david/blog/2018/bivouac-automnal/" title="Accéder à l’article complet">Bivouac automnal</a>,
  543. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  544. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  545. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  546. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  547. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  548. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  549. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  550. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  551. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  552. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  553. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  554. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  555. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  556. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  557. </p>
  558. <p>
  559. On peut <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">échanger par courriel</a>. Si éventuellement tu souhaites que l’on travaille ensemble, tu devrais commencer par consulter le <a href="http://larlet.com">profil dédié à mon activité professionnelle</a> et/ou contacter directement <a href="http://scopyleft.fr/">scopyleft</a>, la <abbr title="Société coopérative et participative">SCOP</abbr> dont je fais partie depuis six ans. Je recommande au préalable de lire <a href="/david/blog/2018/cout-site/" title="Attention ce qui va suivre peut vous choquer">combien coûte un site</a> et pourquoi je suis plutôt favorable à une <a href="/david/pro/devis/" title="Discutons-en !">non-demande de devis</a>.
  560. </p>
  561. <p>
  562. Je ne traque pas ta navigation mais mon
  563. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">hébergeur</abbr>
  564. conserve des logs d’accès.
  565. </p>
  566. </div>
  567. </footer>
  568. <script type="text/javascript">
  569. ;(_ => {
  570. const jumper = document.getElementById('jumper')
  571. jumper.addEventListener('click', e => {
  572. e.preventDefault()
  573. const anchor = e.target.getAttribute('href')
  574. const targetEl = document.getElementById(anchor.substring(1))
  575. targetEl.scrollIntoView({behavior: 'smooth'})
  576. })
  577. })()
  578. </script>