From 8687ba9542d5779580d014100f538d905a00852a Mon Sep 17 00:00:00 2001 From: Jason Nguyen Date: Mon, 26 Oct 2020 14:49:38 -0600 Subject: [PATCH 1/9] Correct display issues in introduction workbook (#336) * Correctly display the "What Are the Benefits of InnerSource?" segement in Update 01-introduction.ascii.doc Update 01-introduction.ascii.doc * Separate answer explanations for Question 2 segment "What are the benefits of InnerSource" --- workbook/01-introduction.asciidoc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/workbook/01-introduction.asciidoc b/workbook/01-introduction.asciidoc index da66fc43..a65d2bfc 100644 --- a/workbook/01-introduction.asciidoc +++ b/workbook/01-introduction.asciidoc @@ -90,6 +90,7 @@ Why 2 is incorrect: The goal of InnerSource is to empower outsiders to contribut Why 3 is correct: A contributor’s code is an excellent starting point for training the contributor. Mentoring can produce educational and personal growth that is even more beneficial than the code contribution itself. And contributors, even if competent and knowledgeable about the code base and team’s goals, can benefit from guidance to bring their contributions in line with a team’s goals and standards. Why 4 is correct: The trusted committer, along with educational and mentoring responsibilities, plays the typical role of a committer on a project, ensuring that the code works well and does not break something else in the application. + ==== SEGMENT: What Are the Benefits of InnerSource? TIP: @@ -125,7 +126,8 @@ Why 1 is incorrect: InnerSource has no effect on funding for a team. It’s true Why 2 is incorrect: InnerSource is not open source. The code is not published outside the company. However, some companies choose to open their code at some point, turning an InnerSource project into an open source one. -Why 3 is correct: InnerSource invites company staff outside the host team to work on the host team’s code. The host team benefits from the outsiders’ understanding of their users’ or consumers’ needs, as well as from the new features added. +Why 3 is correct: InnerSource invites company staff outside the host team to work on the host team’s code. The host team benefits from the outsiders’ understanding of their users’ or consumers’ needs, as well as from the new features added. + Why 4 is incorrect: InnerSource can be a valuable force multiplier during time crunches, bringing people from many teams together to complete high-priority code quickly. But after the crunch, people go back to working on projects within their own teams. ===== Question 3. InnerSource encourages companies to: From 26aa1ece0f2a8cdd1992cda064e7f9f30de1c927 Mon Sep 17 00:00:00 2001 From: Yoshitake Kobayashi Date: Thu, 29 Oct 2020 03:28:22 +0900 Subject: [PATCH 2/9] Translation-ja: Add contributor/ja/02-becoming-a-contributor-article-ja (#337) * Translation-ja: Add contributor/ja/02-becoming-a-contributor-article-ja.asciidoc * Apply suggestion from review. --- ...becoming-a-contributor-article-ja.asciidoc | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 contributor/ja/02-becoming-a-contributor-article-ja.asciidoc diff --git a/contributor/ja/02-becoming-a-contributor-article-ja.asciidoc b/contributor/ja/02-becoming-a-contributor-article-ja.asciidoc new file mode 100644 index 00000000..1cc40750 --- /dev/null +++ b/contributor/ja/02-becoming-a-contributor-article-ja.asciidoc @@ -0,0 +1,69 @@ +== InnerSourceコントリビューターになる + +InnerSourceのコントリビューターは、通常のチームの境界外で活動し、組織のサイロを横断するリンクになります。 +そのため、彼らはこの作業をより効果あるものにするための、いくつかの共通の方法を意識する必要があります。 + +=== マインドセットの共有 + +それでは - あなたはチームの製品に、新しい機能を実装しています。 +この機能を動作させるためには、いくつかの機能が必要です。 +実装に直ぐに取り掛かる代わりに、少し落ち着いて考えます:この機能は一般的な課題なのだろうか? +それは、あなたの組織の他のチームが共有するビジネスドメインで同じように直面しているものなのか? +この機能は、あなたのプロジェクトのドメインと直交するものなのか? +もし当てはまる場合、自分のチームを超えて見渡して:あなたのニーズにフィットするために利用したり改善できる共通のソリューションがあるのか? +あるべきなのか? + +=== ソリューションを共有するメリット + +アフリカには、 "`早く行きたいなら一人で行きなさい。遠くに行きたいなら一緒に行きなさい`" という諺があります。これは、ソフトウェア開発チームにも同じです。 + +もし、早く進みたいのであれば、依存関係を壊すことは良いアイデアです。 +この欠点としては、重複した作業になることです。 +とりわけ、コアロジックを再実装する時には、重複することのコストが独立性のメリットを上回る、非常に現実的なリスクがあります。 + +他のチームとコラボレーションすることで、開発コストを共有できます。 +オープンソースプロジェクトと同様に、あなたが一人で成し遂げられるより大きな何かを、あなたのチームが作ることを可能とします。 + +しかし、それぞれのチームには異なるロードマップがあります! +私は以前、共有のコンポーネントを使おうとしました - それらを再実装するよりも統合することに時間がかかりました。それらのコンポーネントは常に何か欠けてました。 - それに、私の機能リクエストは他のチームのロードマップで優先的になることはありませんでした! + +従来のプロジェクトと比べると、InnerSourceのプロジェクトにはコントリビューターの役割があります。 +あなたは共通のソリューションに新しい機能があればと思うこともあるでしょう。 +コントリビューターとして、あなたにはソースコードをチェックアウトして変更を加え、改良したバージョンを利用する自由があります。 + +あなたのタイムラインで、ホストチームでは同じ優先度を持たないバグの修正が緊急に必要になることもあるでしょう。 +コントリビューターになることで、あなた自身が行動し、ホストチームをバグ修正でサポートすることができるようになります。 + +この作業方法は、多くの点でマインドセットの変更が必要となります: 機能やバグの修正を待つ代わりに、問題を回避する代わりに、そこには第3の解決策があります。あなたの時間や労力を費やしてInnerSourceプロジェクトにおけるあなたのニーズを確認し - それから共有されたプロジェクトに直接変更を加えます。 +そして、あなたにはコーディングスキルに加え、InnerSourceプロジェクトで成功するためのコミュニケーションスキルが必要です - あなたのニーズを明確化し、あなたのチームとホストチームの両方で機能するソリューションを実現するために。 + +"しかし、私はプロジェクトをフォークして、そこに変更を加え、この調整のオーバーヘッドから自身を守りました!" +確かに、プロジェクトをフォークすることは、あなたの仕事を終わらせる方法です。 +長期的な場合を除いては、これはあなたのチームがフォークしたバージョンをメンテナンスし、ホストチームが作成する新しいリリースのいずれにも、その変更を追随させる必要があるということを意味します。 +あなたの変更をホストチームにコントリビューションすることは、彼らのコンポーネントに関するより深い知識からメリットを得られるということも意味します。 +彼らは、本番でしか明らかにならないようなパッチの問題を明らかにするかも知れません。 + +優れたコントリビュータは、作業を複製する代わりに依存関係を導入してコンポーネントを再利用することが技術的にもビジネス的にも意味がある時に、気軽に声をかけることができます。彼らは、InnerSouceコントリビューションのメリットを説明するために、マネージメントに話をすることができます。 + +=== InnerSourceコントリビューションのスコープ + +では、Inner__Source__ とは、__ソース__コード だけのことなのでしょうか? +もちろん、違います。 +もし、あなたのチームのビジネスが外部のコンポーネントに依存していたら、あなたはそれが適切にメンテナンスされ動作することを確認したいでしょう。 +InnerSouceのコントリビューターとしては、あなたはホストチームを複数の方法で支援できます。 +コンポーネントを利用している際の問題を報告することは、価値あるコントリビューションです。 +コードが期待通りに動作していないことを示すテストケースを作成したり修正することは価値があります。 +そして、ドキュメントを改善することは、他の人がそれを利用したりコントリビューションしたりするために費やす時間を少なくします。 +他のユーザをサポートすること、バグのトリアージを支援することは、価値あるコントリビューションです。 +ビルドの改善も、価値あるコントリビューションの例です。 + +要約すると、どのようなコントリビューションでも、小さすぎるということはありません。 +これは私が https://github.com/tensorflow/models/pull/4784[tensorflow/models] に対して作成したものです。 +単純なグラフのラベル変更です。 + +=== この記事のまとめ + +この記事では、コントリビュータになるために必要なことについて学びました。 +私達は共有のマインドセットを見ました。 +ソリューションを共有することのメリットについて深く掘り下げました。 +最後に、InnerSourceのコントリビューションのスコープが、一般的にどのようなものとなるかを見てみました。 From 15e2eddae4c98a8eb08ee9c9935267ff096a42fe Mon Sep 17 00:00:00 2001 From: RJPlog <44948239+RJPlog@users.noreply.github.com> Date: Thu, 29 Oct 2020 17:28:40 +0100 Subject: [PATCH 3/9] 256 translate trusted committer chapter07 (#323) * draft translation chapter07 * german translation trusted committer chapter07 * suggested changes after review of arnom-ms incorporated --- .../07-becoming-a-trusted-committer.asciidoc | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 trusted-committer/de/07-becoming-a-trusted-committer.asciidoc diff --git a/trusted-committer/de/07-becoming-a-trusted-committer.asciidoc b/trusted-committer/de/07-becoming-a-trusted-committer.asciidoc new file mode 100644 index 00000000..fc159128 --- /dev/null +++ b/trusted-committer/de/07-becoming-a-trusted-committer.asciidoc @@ -0,0 +1,22 @@ +== Wie wird man ein _Trusted Committer_ + +Die Rolle des _Trusted Committer_ ist zwar anspruchsvoll, aber auch erfüllend. Wenn dich dieses Tutorial interessiert, dann möchtest du vielleicht wissen, wie man zu einem _Trusted Committer_ wird, und ob du die richtige Person für diese Aufgabe bist. + +InnerSource Communities funktionieren nach denselben Prinzipien wie Open Source Communities, eines davon ist Meritokratie. In einer Meritokratie wird Ansehen basierend auf Talent, Anstrengung und Erreichtem erworben. Das bedeutet, dass das Ansehen und Privilegien, die mit der Rolle des _Trusted Committers_ einhergehen, verdient werden müssen. +Transparenz, ein weiterer Wert von Open Source, spielt ebenfalls eine wesentliche Rolle dabei, Talent, Anstrengung und Erreichtes in der gesamten Gemeinschaft sichtbar zu machen. + +Der Prozess, offiziell ein _Trusted Committer_ zu werden, unterscheidet sich von Community zu Community und hängt davon ab, wo du persönlich in deiner Inner Source Reise stehst und wird sich im Lauf der Zeit entwickeln. In neu gegründeten Communities übernehmen die Gründer oft selbst die Rolle des _Trusted Committers_. Wenn die Community dann wächst, oder in größeren Communities, werden _Trusted Committer_ normalerweise nominiert oder von den https://innersourcecommons.org/resources/learningpath/contributor/index[Contributors] der Community gewählt. +Trotzdem sollte die Rolle des _Trusted Committers_ freiwillig übernommen werden, denn sie erfordert großen Zeitaufwand und Engagement um erfolgreich zu sein. + +Welche Kriterien gelten bei der Nominierungen von https://innersourcecommons.org/resources/learningpath/contributor/index[Contributors] für die Rolle des _Trusted Committers_? Was benötigt man, um die Rolle des _Trusted Committers_ erfolgreich auszufüllen? Zuallererst müssen potentielle _Trusted Committer_ ihre tiefe technische Kompetenz während ihrer Arbeit in der Community unter Beweis stellen. Zusätzlich dazu müssen sie zeigen, dass sie wirkungsvoll mit den Kollegen der Community, und idealerweise genauso mit den Product Ownern und dem Management, zusammen arbeiten können. + +Auf dieselbe Art müssen sie den Willen und die Geduld aufweisen, ihre Fähigkeiten zu nutzen und bewusst sich Zeit nehmen, um _Contributors_ weiter zu qualifizieren. Schließlich erfordert die Erfüllung der Rolle des _Trusted Committers_ eine gewisse emotionale Reife, um mit stressvollen sozialen Situationen umzugehen die mit Sicherheit ab und zu aufkommen. +Contributors, welche diese Kriterien erfüllen, sind nach unserer Meinung gute Kandidaten für potentielle _Trusted Committers_. + +Die Rolle des _Trusted Committers_ wird nicht für alle Contributors attraktiv sein, bedeutet es doch, dass man weniger Zeit verbringt, selbst zu programmieren. Als _Trusted Committer_ vorgeschlagen zu werden kann sogar herabstufend empfunden oder als negatives Feedback bezüglich der eigenen Programmierfähgigkeiten aufgefasst werden. Aber das Gegenteil ist der Fall. Als _Trusted Committer_ nominiert zu werden, bedeutet normalerweise, dass man deine wertvollen Beiträge erkannt hat und in dir das Potential weiter zu wachsen und zu führen sieht. Die Rolle des _Trusted Committers_ gib dir mehr Einfluß auf die Entwicklung der Codebasis und macht dich definitiv zu einem vollständigeren Entwickler. Contributors zu erklären, wie die Software funktioniert, die Rolle führt häufig zu neuen Erkenntnissen seitens des _Trusted Committers_, und hilft Möglichkeiten zu identifizieren die Software weiter zu verbessern. + +Ob es einer InnerSource Community einen oder mehrere _Trusted Committer_ gibt, hängt von der Größe und dem Risiko ab, welches mit ihrer Software verbunden ist. +Die Rolle des _Trusted Committers_ ist zeitaufwändig, und nicht jeder ist gewillt oder hat die Möglichkeit diese Verpflichtung einzugehen. Aus diesem Grund nutzen mache Unternehmen ein Rotationssystem, in dem sich mehrere _Trusted Committer_ die Arbeitslast teilen, und diejenigen _Trusted Committer_, die gerade nicht an der Reihe sind, können sich ausschließlich technischen Themen widmen. Mehr als einen _Trusted Committer_ zu haben macht es auch leichter, wenn jemand das Unternehmen verlässt oder wenn jemand sich aus der Rolle in eine neue Aufgabe verändert. Für diesen Fall ist es wichtig, dass schon andere _Trusted Committer_ bereit stehen, die die Aufgaben übernehmen können um Kontinuität in der Gemeinschaft sicherzustellen. + +Zusammengefasst erwirbt man sich die Rolle des _Trusted Committer_ durch Erstellen von wertigen Beiträgen zum Wohl der Community - sowohl technisch als auch sozial. In einer gut aufgestellten Community hast du andere _Trusted Committer_ an deiner Seite. Als _Trusted Committer_ wirst du weniger Zeit verbringen selbst zu programmieren, aber wenn du als Multiplikator agierst, wirst du letztendlich deinen Wertbeitrag verstärken und dein eigenes Wachstum beschleunigen. + From 6de34b52f97f1fb354857ccebad64a0290873c4a Mon Sep 17 00:00:00 2001 From: Willem Jiang Date: Tue, 3 Nov 2020 02:45:57 +0800 Subject: [PATCH 4/9] Polish the document of trusted committer chinese translation (#340) --- trusted-committer/zh/01-introduction-zh.asciidoc | 4 ++-- .../zh/02-ensuring-product-quality-zh.asciidoc | 10 +++++----- .../zh/03-keeping-the-community-healthy-zh.asciidoc | 4 ++-- .../zh/04-uplevelling-community-members-zh.asciidoc | 4 ++-- .../zh/05-lowering-the-barriers-to-entry-zh.asciidoc | 4 ++-- .../06-advocating-for-the-communitys-needs-zh.asciidoc | 10 +++++----- .../zh/07-becoming-a-trusted-committer-zh.asciidoc | 4 ++-- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/trusted-committer/zh/01-introduction-zh.asciidoc b/trusted-committer/zh/01-introduction-zh.asciidoc index 2d6031af..8b4475ba 100644 --- a/trusted-committer/zh/01-introduction-zh.asciidoc +++ b/trusted-committer/zh/01-introduction-zh.asciidoc @@ -4,7 +4,7 @@ Trusted Committer角色是InnerSource社区中的关键角色之一。将Trusted Committer视为你所在的社区中所信任的对象,他们可以通过重要的技术决策和指导贡献者来最终获得收益。我们对Trusted Committer的要求很高,同时这个岗位也会得到很高的回报。这个角色并不是一个自以为是的把关者,甚至他对任何InnerSource社区的成功都至关重要。 -一般而言,Trusted Committer角色是由其职责而不是其特权定义的。在很高程度上,可信任提交者代表其InnerSource社区和该社区正在开发的产品的利益。他们关心社区和产品的健康。因此,作为Trusted Committer,您将同时承担面向技术和社区的责任。我们将在以下各章节中探讨这两个方面。 +一般而言,Trusted Committer角色是由其职责而不是其特权定义的。在很高程度上 Trusted Committer 代表其InnerSource社区和该社区正在开发的产品的利益。他们关心社区和产品的健康。因此,作为Trusted Committer,您将同时承担面向技术和社区的责任。我们将在以下各章节中探讨这两个方面。 在详细介绍Trusted Committer实际功能之前,让我们花一些时间从高度抽象的角度将Trusted Committer角色与InnerSource中的其他角色进行对比,并解释为什么我们认为该名称既恰当又重要。让我们从 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]角色开始。顾名思义, https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]为InnerSource社区做出了贡献。这些贡献可能是代码或非代码工件,例如错误报告,功能请求或文档。 @@ -32,7 +32,7 @@ Trusted Committer负有各种责任,包括: 3. https://innersourcecommons.org/resources/learningpath/trusted-committer/zh/05/[_减少贡献的障碍(Reducing the barriers to making contributions)_] -4. https://innersourcecommons.org/resources/learningpath/trusted-committer/zh/04/[_提升社区(Upleveling the community)_] +4. https://innersourcecommons.org/resources/learningpath/trusted-committer/zh/04/[_牵引社区(Upleveling the community)_] 5. https://innersourcecommons.org/resources/learningpath/trusted-committer/zh/06/[_倡导社区的需求 (Advocating the community’s needs)_] 我们将在接下来的章节中更深入地探讨这些职责,并在本文结尾处探索成为Trusted Committer的途径. diff --git a/trusted-committer/zh/02-ensuring-product-quality-zh.asciidoc b/trusted-committer/zh/02-ensuring-product-quality-zh.asciidoc index d74f8b90..984ac29a 100644 --- a/trusted-committer/zh/02-ensuring-product-quality-zh.asciidoc +++ b/trusted-committer/zh/02-ensuring-product-quality-zh.asciidoc @@ -8,12 +8,12 @@ Trusted Committer的工作是在其社区中交流和阐明质量标准,并以 Trusted Committer还需要确保社区拥有生产高质量软件所需的基础结构和工具。同行评审通常会作为拉取请求(PRs)的一部分,通常用于确保质量。尽管每个人都可以通过提出重要的进展来启动和参与项目,但是通常只有Trusted Committer才能最终接受、合并或拒绝贡献。这就是我们早先所说的“Trusted Committer可以将代码推向生产环境”的意思。Trusted Committer还应该在PR期间确认贡献者不要超过截止日期进行贡献。 -也就是说,实现这一目标最终是 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]的工作。Trusted Committer的工作不是默认接受所有贡献,而仅接受在质量和范围方面符合定义标准的贡献。Trusted Committer应避免重写贡献者的代码去让它们尽可能符合规定,即使这意味着要花费更多时间在PR中为 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]提供支持。Trusted Committer应具有长远的眼光,并了解这种支持是对社区寿命的一种投资,从长远来看,它将提高社区的发展速度。 +也就是说,实现这一目标最终是 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]的工作。Trusted Committer的工作不是默认接受所有贡献,而仅接受在质量和范围方面符合定义标准的贡献。Trusted Committer应避免重写贡献者的代码去让它们尽可能符合规定,即使这意味着要花费更多时间在PR中为 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]提供支持。Trusted Committer应具有长远的眼光,并了解这种支持是对社区的一种长期投资,从长远来看,它将提高社区的发展速度。 -有时项目要求或限制不是都能预判的,而是在开发过程中被发现的。Trusted Committer还会负责为 https://innersourcecommons.org/resources/learningpath/product-owner/index[_产品所有者(Product Owner)_]和贡献者(Contributor)捕获并记录这些发现。 +有时项目需求或限制不是都能预先设计的,而是在开发过程中被发现的。Trusted Committer还会负责为 https://innersourcecommons.org/resources/learningpath/product-owner/index[_产品所有者(Product Owner)_]和贡献者(Contributor)捕获并记录这些发现。 -但是,Trusted Committer在控制质量方面的权限超出了普通PR的范围。Trusted Committer从战略角度考虑质量,并确保所构建软件的寿命。从确保代码的整洁到维护整个软件的概念完整性,这涉及到面向整体代码的责任。还需要进行面向管理的任务,例如确保给社区足够的时间来重构其软件,或者在需要时为支持质量改进而推迟发布日期。Trusted Committer的工作效率与代码运行状况密切相关。 +但是,Trusted Committer在控制质量方面的权限超出了普通PR的范围。Trusted Committer从战略角度考虑质量,并确保所构建软件的长期生命力。从确保代码的整洁到维护整个软件的概念完整性,这涉及到面向整体代码的责任。还需要完成面向管理的任务,例如确保给社区足够的时间来重构其软件,或者在需要时为支持质量改进而推迟发布日期。Trusted Committer的工作效率与代码健康状况密切相关。 -如果没有后者,则Trusted Committer将不得不花费大量宝贵的时间记录错误或脆弱的体系结构和验证解决办法,并且将会没有足够的时间花在发展和指导 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]上。 +如果没有后者,则Trusted Committer将不得不花费大量宝贵的时间记录错误或在脆弱的体系结构和验证解决办法,并且将会没有足够的时间花在发展和指导 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]上。 -总而言之,确保产品质量是Trusted Committer的关键责任。他们设定质量标准并以身作则。他们参与PR并帮助 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]达到质量标准。并且还需要负责软件的长期运行状况。 +总而言之,确保产品质量是Trusted Committer的关键责任。他们设定质量标准并以身作则。他们参与PR并帮助 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]达到质量标准。并且还需要负责维护软件的长期健康。 diff --git a/trusted-committer/zh/03-keeping-the-community-healthy-zh.asciidoc b/trusted-committer/zh/03-keeping-the-community-healthy-zh.asciidoc index 6389f745..27a5ce70 100644 --- a/trusted-committer/zh/03-keeping-the-community-healthy-zh.asciidoc +++ b/trusted-committer/zh/03-keeping-the-community-healthy-zh.asciidoc @@ -2,7 +2,7 @@ 导言指出,Trusted Committer既要承担技术责任,又要承担社区责任。仅关注代码和代码健康是不够的。为了实现长期的目标,Trusted Committers应该努力保持软件构建社区的健康。因此,他们必须在确保产品质量和保持健康社区之间取得平衡。 -健康的社区是什么样的?很简单,在一个健康的社区中, https://innersourcecommons.org/resources/learningpath/contributor/index[_贡献者(Contributor)_]往往会持续进行贡献,将大部分时间花费在开发软件上,并从中提升自己的能力。这样的话,一个健康的社区将能不断发展。 +健康的社区是什么样的?很简单,在一个健康的社区中, https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]往往会持续进行贡献,将大部分时间花费在开发软件上,并从中提升自己的能力。这样的话,一个健康的社区将能不断发展。 为什么 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]会加入并停留在社区中?有些人这样做是因为他们认同社区的宗旨或使命。清楚地表达和贯彻社区的宗旨是Trusted Committer的工作。人们通常认识不到这一点的重要性,但在营销社区及其产品的过程中,这确实是必不可少的。 @@ -10,7 +10,7 @@ 如果人们还倾向于留在社区里,证明他们知道在InnerSource社区工作是获得新技能和个人成长的绝好机会。这其实是Trusted Committer的角色真正重要的地方。Trusted Committer通常会成为初级开发人员的指导者,并且在PR期间去指出需要改进的地方,还详细说明了为什么需要改进以及如何进行改进。他们提供了更改背后的理论或经验,并为更改的最佳方法提供了建议。这样,Trusted Committer可以提高成员社区中的学习速度,远远超过他们在传统软件开发项目中的学习速度。 -我们认为,Trusted Committer应在 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_] PR期间就进行指导,而不要等到发布日期,除非确实没有这个精力。PR期间,良好指导可提高贡献者(contributor)的信任度和参与度,因此吸引更多的贡献。我们将在“升级社区”中对此进行更多讨论。 +我们认为,Trusted Committer应在 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_] PR期间就进行指导,而不要等到发布日期,除非确实没有这个精力。PR期间,良好指导可提高 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]的信任度和参与度,因此吸引更多的贡献。我们将在“提升社区”中对此进行更多讨论。 最后,有些人会停留在InnerSource社区中,是因为他们开始专注于开发软件,而不是去做一些不实际、浪费性的工作,尤其是在大型公司中——他们太注重流程。在此背景下,Trusted Committer的工作是通过交流和制定有用的贡献准则来确保贡献者真正专注于其项目。 diff --git a/trusted-committer/zh/04-uplevelling-community-members-zh.asciidoc b/trusted-committer/zh/04-uplevelling-community-members-zh.asciidoc index bcba395b..14d93506 100644 --- a/trusted-committer/zh/04-uplevelling-community-members-zh.asciidoc +++ b/trusted-committer/zh/04-uplevelling-community-members-zh.asciidoc @@ -1,8 +1,8 @@ -== 升级社区成员 +== 牵引社区成员 在InnerSource社区中会存在有一个深入参与的过程。期间一定会有不了解这个社区的阶段。首先,新手可能对社区和社区内的产品感兴趣,但尚未使用过它。然后会有使用过产品但没有贡献过的用户。然后是至少做出过一次贡献的 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_],最后是负责整体软件和社区的Trusted Committer。作为Trusted Committer,您有责任令社区成员沿着这一连续性前进,并提升他们的贡献能力。从这个意义上讲,Trusted Committer在其社区中充当力量倍增器。 -对于Trusted Committer而言,营销其产品和社区以增加新用户和消费者数量非常重要。他们还应该通过与消费者保持交流去引导他们做出贡献,并尝试引起潜在 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]的利益,并使之与社区的利益保持一致。通常,有效的办法是,让 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]参与贡献的是有益于其部门或公司角色的工作。开发工具和自动化就是很好的例子。 +对于Trusted Committer而言,产品营销和社区增加新用户和消费者数量非常重要。他们还应该通过与消费者保持交流去引导他们做出贡献,并尝试牵引潜在 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]的利益,并使之与社区的利益保持一致。通常,有效的办法是,让 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]参与贡献的是有益于其部门或公司角色的工作。开发工具和自动化就是很好的例子。 最后,Trusted Committer有责任在鼓励大家完成挑战性任务、指导他们完成工作的过程中,来识别和支持有成长潜力的贡献者。我们认为,这是Trusted Committer的最高责任,对于Trusted Committer和 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]来说都是非常有价值的。我们听过一些Trusted Committer说,指导和推动人们去提升自己的能力,比花时间在编写软件上更重要。 diff --git a/trusted-committer/zh/05-lowering-the-barriers-to-entry-zh.asciidoc b/trusted-committer/zh/05-lowering-the-barriers-to-entry-zh.asciidoc index 05469ef0..4e1b73da 100644 --- a/trusted-committer/zh/05-lowering-the-barriers-to-entry-zh.asciidoc +++ b/trusted-committer/zh/05-lowering-the-barriers-to-entry-zh.asciidoc @@ -8,7 +8,7 @@ 这就是为什么对于Trusted Committer而言,使潜在 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]向贡献者成长的重要性。有很多事情可以帮助到您实现这个目的: -* 在每个代码存储库中都会有一个README.md。优秀的README.md解释了存储库中的内容及其用途。此外,它应提供有关如何获取,构建,测试和使用存储库中软件的详细说明,包括有关许可证的信息。 +* 在每个代码存储库中都会有一个README.md。优秀的README.md解释了代码库中的内容及其用途。此外,它应提供有关如何获取,构建,测试和使用代码库中软件的详细说明,包括有关许可证的信息。 * 拥有一个良好的CONTRIBUTING.md,其中概述了 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]的期望。它应回答常见问题,例如: ** 如何提交错误报告或功能请求? @@ -25,6 +25,6 @@ 有两种常见的贡献模型:_共享代码库_ 以及 _fork和join_。两者都有优势,作为Trusted Committer,你应该希望社区同时支持这两种模型,以适应贡献者和潜在贡献者的不同需求。您的贡献者经常会遇到有关贡献过程或社区本身的问题,而必须有人来回答这些问题。因此,对于任何InnerSource社区来说,重要的是要有一个或多个联系人可以回答这些问题。通常,来自“Trusted Committer”组中的某个人是联系人,否则,他们需要确保有“随时待命”的社区成员。 -帮助潜在的 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]确定需要哪些贡献也很重要。这些可以是代码贡献,也可以是非代码贡献,例如编写文档,创建插图或组织事件。一种常见的实现方法是在社区中设置“新手任务”,或为 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]提供一个任务市场让他们能够挑选任务。 +帮助潜在的 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]确定需要哪些贡献也很重要。这些可以是代码贡献,也可以是非代码贡献,例如编写文档,创建插图或组织活动。一种常见的实现方法是在社区中设置“新手任务”,或为 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]提供一个任务市场让他们能够挑选任务。 总而言之,对于公司环境中的InnerSource社区而言,将贡献的障碍降低到最低水平,以允许更多人贡献是非常重要的。这意味着成员既可以访问有用的文档,也可以回答任何问题,以此鼓励协作。总之,Trusted Committer应确保加入社区和参与贡献对他人来说是良好的经历。 diff --git a/trusted-committer/zh/06-advocating-for-the-communitys-needs-zh.asciidoc b/trusted-committer/zh/06-advocating-for-the-communitys-needs-zh.asciidoc index 5c40d674..3d6fd228 100644 --- a/trusted-committer/zh/06-advocating-for-the-communitys-needs-zh.asciidoc +++ b/trusted-committer/zh/06-advocating-for-the-communitys-needs-zh.asciidoc @@ -1,11 +1,11 @@ == 倡导社区需求 -InnerSource社区存在于协作的环境中,因此比开放源社区更受限制。有时,人们业务部门的利益与社区的利益并不一致。Trusted Committer对项目应有长远的安排和打算,他们了解健康的社区是健康代码的前提。这就是为什么许多InnerSource计划都以Apache Way的座右铭 http://theapacheway.com/community-over-code/[_Community over code._] 为指引的原因。另一方面,业务部门也会自然地关注InnerSource社区生产的产品。他们希望看到在短期或中期内,这能帮助企业提高利润。 +InnerSource社区存在于公司内部协作的环境中,因此比开放源社区更受限制。有时,人们业务部门的利益与社区的利益并不一致。Trusted Committer对项目应有长远的安排和打算,他们了解健康的社区是健康代码的前提。这就是为什么许多InnerSource初始团队都以Apache Way的座右铭 http://theapacheway.com/community-over-code/[_Community over code._] 为指引的原因。另一方面,业务部门也会自然地关注InnerSource社区生产的产品。他们希望看到在短期或中期内,这能帮助企业提高利润。 -在此潜在的冲突中,Trusted Committer将发挥至关重要的作用。Trusted Committer与组织建立了信任,并在此信任的基础上,倡导维护社区利益和保持公司软件的长期健康。他们负责传达技术风险以及与社区有关的管理风险。同时,Trusted Committer需要具有战略性,并在其公司的容忍度、自由度内工作。 +在此潜在的冲突中,Trusted Committer将发挥至关重要的作用。Trusted Committer与组织建立了信任,并在此信任的基础上,倡导维护社区利益和保持公司软件的长期健康。他们负责传达技术风险以及与社区有关的管理风险。同时,Trusted Committer需要具有战略视角,并在其公司的容忍度、自由度内工作。 -Trusted Committer还需要确保社区和个人贡献者的工作获得公众认可。公共信誉是用来支付捐赠者,特别是自愿捐赠者的货币。好的办法是公开表彰有价值的贡献者,并确保他的领导了解他们的贡献。忽视给予信誉可能会使个人贡献者感到沮丧,并损害社区的健康。这可能发生在尚未习惯InnerSource工作模式的公司中,或者当InnerSource社区开发的软件在后台运行,但管理人员根本不了解社区的贡献时。一个好的Trusted Committer将与管理层合作并倡导为公共信誉做贡献。不是出于恶意的抹杀贡献是很容易解决的。 +Trusted Committer还需要确保社区和个人贡献者的工作获得公众认可。公共信誉是用来支付贡献者,特别是自愿贡献者的货币。好的办法是公开表彰有价值的贡献者,并确保他的领导了解他们的贡献。忽视给予信誉可能会使个人贡献者感到沮丧,并损害社区的健康。这可能发生在尚未习惯InnerSource工作模式的公司中,或者当InnerSource社区开发的软件在后台运行,但管理人员根本不了解社区的贡献时。一个好的Trusted Committer将与管理层合作并倡导为公共信誉做贡献。不是出于恶意的抹杀贡献错误是很容易修复的。 -另一个需要Trusted Committer去重视的常见情况是,没有给 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]足够的时间或权限。当社区正在贡献者部门以外的产品上工作,因此与他们的工作目标无关时,就会发生这种情况。在这种情况下,Trusted Committer应与 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]的工作领导和游说者进行讨论,以相应的措施去解决。 +另一个需要Trusted Committer去重视的常见情况是,没有给 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]足够的时间或权限。当社区正在贡献者部门以外的产品上工作,因此与他们的工作目标无关时,就会发生这种情况。在这种情况下,Trusted Committer应与 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]的工作领导进行沟通,并寻找相应的替代方案。 -总之,在许多情况下,Trusted Committer需要平衡个人贡献者和整个社区的利益。Trusted Committer应该清楚认识到,社区可以为组织提供的价值取决于社区的健康和寿命,并最终取决于两者之间的相互信赖关系。 +总之,在许多情况下,Trusted Committer需要平衡个人贡献者和整个社区的利益。Trusted Committer应该清楚认识到,社区可以为组织提供的价值取决于社区的健康和长期发展以及社区与组织之间的相互信赖关系。 diff --git a/trusted-committer/zh/07-becoming-a-trusted-committer-zh.asciidoc b/trusted-committer/zh/07-becoming-a-trusted-committer-zh.asciidoc index db48caf3..2ee4eff3 100644 --- a/trusted-committer/zh/07-becoming-a-trusted-committer-zh.asciidoc +++ b/trusted-committer/zh/07-becoming-a-trusted-committer-zh.asciidoc @@ -1,8 +1,8 @@ -== 如何成为受信任贡献者 +== 如何成为Trusted Committer 社区对于Trusted Committer的要求是非常高的,但作为一个Trusted Committer,会让人非常有成就感。如果你想通过成为一个Trusted Committer得到成长,您可能会问:我要怎样成为一个Trusted Committer,我会是合适的人选吗? -Inner Source社区遵循一些与开源社区相同的原则,其中之一就是精英制度。在精英制度中,权力取决于个人的才能、努力和成就。换句话说,就等同于是Trusted Committer角色附带的责任和特权是需要通过做贡献赢得的。透明度是另一个开源价值,它也发挥了至关重要的作用,因为它使人才的努力和成就对整个社区可见。 +InnerSource 社区遵循一些与开源社区相同的原则,其中之一就是精英制度。在精英制度中,权力取决于个人的才能、努力和成就。换句话说,就等同于是Trusted Committer角色附带的责任和特权是需要通过做贡献赢得的。透明度是另一个开源价值,它也发挥了至关重要的作用,因为它使人才的努力和成就对整个社区可见。 正式成为Trusted Committer的过程每个社区都会有不同,主要取决于你在InnerSource中所处的社区,并且规则可能在不断变化。在基层社区中,创始人通常也自动承担Trusted Committer的角色。随着社区的发展,社区或现有的Trusted Committer可能会提名,并以投票的方式发展一名 https://innersourcecommons.org/resources/learningpath/contributor/zh/index[_贡献者(Contributor)_]成为Trusted Committer。理想情况下,被提名的贡献者需要自愿担任Trusted Committer角色,因为它需要大量的时间和奉献精神才能成功。 From 7f81c0bf8a3ee100133ad61434d223b2cb1c7e7f Mon Sep 17 00:00:00 2001 From: Jason Nguyen Date: Tue, 3 Nov 2020 10:36:42 -0700 Subject: [PATCH 5/9] correct display for a couple of segments in 02-trusted-commiter (#342) --- workbook/02-trusted-committer.asciidoc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/workbook/02-trusted-committer.asciidoc b/workbook/02-trusted-committer.asciidoc index 032c53ab..4288bb0e 100644 --- a/workbook/02-trusted-committer.asciidoc +++ b/workbook/02-trusted-committer.asciidoc @@ -68,7 +68,7 @@ Why 4 is incorrect: Promotions, like other personnel matters, are still handled ====== Correct answers: 1 and 3 -Why 1 is correct: Trusted committers should embody all the traits of a good community member, both in their coding skills and in their interactions. Therefore, contributors are likely emulate the trusted committers’ behavior and hopefully to become trusted committers themselves. +Why 1 is correct: Trusted committers should embody all the traits of a good community member, both in their coding skills and in their interactions. Therefore, contributors are likely to emulate the trusted committers’ behavior and hopefully to become trusted committers themselves. Why 2 is incorrect: InnerSource, done properly, puts responsibility on the contributors for deciding what code needs to change and how to change it. Trusted committers can make sure that the code follows style guidelines and doesn’t break anything else. However, the trusted committer is not part of management. InnerSource reduces the need for managers to direct projects at a detailed level. @@ -187,6 +187,7 @@ Why 2 is correct: As people gain both skills and confidence, they can offer thes Why 3 is correct: One of the crucial purposes of mentoring is to enable each contributor to do better each time, and take on a bigger scope in the project. Why 4 is correct: As contributors become more sophisticated, their productivity increases and their contributions become more significant. Furthermore, they can help set goals that improve the overall health of the project. + ==== SEGMENT: Lowering the Barriers to Entry TIP: @@ -225,6 +226,7 @@ Why 1 and 2 are correct; Both of these files should be read by contributors befo Why 3 is correct: Step-by-step procedures, where they can be defined, help turn the abstract into the concrete. It’s easier to follow a clear procedure than to apply general principles. Why 4 is correct: The trusted committer offers personal guidance to contributors. It’s useful to preserve such interactions in written form somewhere where other contributors can read and hopefully learn from them. + ==== SEGMENT: Advocating for the Community's Needs TIP: From 55d75ed177a2d9482e89a49d9bbb0840b385472d Mon Sep 17 00:00:00 2001 From: Tom Sadler Date: Wed, 4 Nov 2020 22:17:39 +0000 Subject: [PATCH 6/9] Add article contributors in learning path markdown metadata. --- .gitignore | 1 + scripts/README.md | 7 +- scripts/generate_learning_path_markdown.js | 217 +++++++++++---------- scripts/get_contributors.js | 37 ++++ scripts/package-lock.json | 96 +++++++++ scripts/package.json | 2 + 6 files changed, 254 insertions(+), 106 deletions(-) create mode 100644 scripts/get_contributors.js diff --git a/.gitignore b/.gitignore index 433ec740..1ccf4fbf 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ \.DS_Store scripts/node_modules scripts/learningpath +scripts/.env \ No newline at end of file diff --git a/scripts/README.md b/scripts/README.md index 058afdd2..decd70b7 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -19,6 +19,11 @@ node substitute_article_urls.js isc A node script to generate markdown files required for hosting Learning Path on innersourcecommons.org. +This script requires a [GitHub access token](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token), as it uses the GitHub API to get Learning Path contributors. Your token does not require any scopes, as the Learning Path is Open Source. To provide this, create a `.env` file in this directory in the following format: +``` +TOKEN= +``` + ### Usage: ``` npm ci @@ -36,7 +41,7 @@ If so, then do both of the following: * update the ["sections" config](https://github.com/InnerSourceCommons/InnerSourceLearningPath/blob/master/scripts/generate_learning_path_markdown.js#L37) with the language code of the articles for the appropriate section. Open a pull request for the change. * update the [Learning Path landing page](https://github.com/InnerSourceCommons/innersourcecommons.org/blob/master/resources/learningpath/index.md) with a link to your new language pages. - + 3. Run **generate_learning_path_markdown.js** as described above. 3. `cp -r learningpath/* /resources/learningpath/`. 3. Open a pull request with the modified files in the [InnerSourceCommons/innersourcecommons.org] repo. diff --git a/scripts/generate_learning_path_markdown.js b/scripts/generate_learning_path_markdown.js index 3fd33f84..5b03058e 100644 --- a/scripts/generate_learning_path_markdown.js +++ b/scripts/generate_learning_path_markdown.js @@ -1,120 +1,127 @@ -const fs = require('fs') -const YAML = require('yaml') -const { EOL } = require('os') -const { join } = require('path') +(async() => { + const fs = require('fs') + const YAML = require('yaml') + const { EOL } = require('os') + const { join } = require('path') + const getContributors = require('./get_contributors') -const mkdirSync = (dir) => { - try { - fs.mkdirSync(dir) - } catch (e) { - if (e.code !== 'EEXIST') { - console.log(e) + const mkdirSync = (dir) => { + try { + fs.mkdirSync(dir) + } catch (e) { + if (e.code !== 'EEXIST') { + console.log(e) + } } } -} -const getArticleFiles = (path) => { - return fs.readdirSync(path).reduce((articles, filename) => { - const filePath = `${path}/${filename}` - if (filePath.match(/\d\d/) && !filePath.includes('-script.asciidoc')) { - return [...articles, { - filePath, - asciiDoc: fs.readFileSync(filePath, 'utf-8') - }] - } else { - return articles - } - }, []) -} + const getArticleFiles = (path) => { + return fs.readdirSync(path).reduce((articles, filename) => { + const filePath = `${path}/${filename}` + if (filePath.match(/\d\d/) && !filePath.includes('-script.asciidoc')) { + return [...articles, { + filePath, + asciiDoc: fs.readFileSync(filePath, 'utf-8') + }] + } else { + return articles + } + }, []) + } -const writeMarkdownFile = (filePath, frontMatter) => { - const frontMatterTerminator = '---' - const originStatement = '' - const output = [frontMatterTerminator, YAML.stringify(frontMatter).trim(), frontMatterTerminator, originStatement].join(EOL) - fs.writeFileSync(filePath, output) -} + const writeMarkdownFile = (filePath, frontMatter) => { + const frontMatterTerminator = '---' + const originStatement = '' + const output = [frontMatterTerminator, YAML.stringify(frontMatter).trim(), frontMatterTerminator, originStatement].join(EOL) + fs.writeFileSync(filePath, output) + } -const sections = [ - { - learning_path_group: 'Introduction', - dirName: 'introduction', - workbook: '01-introduction.asciidoc', - translations: ['de', 'it', 'ja', 'zh'], - renderArticles: true - }, - { - learning_path_group: 'Trusted Committer', - dirName: 'trusted-committer', - workbook: '02-trusted-committer.asciidoc', - translations: ['de', 'zh'], - renderArticles: true - }, - { - learning_path_group: 'Contributor', - dirName: 'contributor', - workbook: '04-contributor.asciidoc', - translations: ['ja', 'zh'], - renderArticles: true - }, - { - learning_path_group: 'Product Owner', - dirName: 'product-owner', - workbook: '03-product-owner.asciidoc', - translations: [], - renderArticles: false - }, -] + const sections = [ + { + learning_path_group: 'Introduction', + dirName: 'introduction', + workbook: '01-introduction.asciidoc', + translations: ['de', 'it', 'ja', 'zh'], + renderArticles: true + }, + { + learning_path_group: 'Trusted Committer', + dirName: 'trusted-committer', + workbook: '02-trusted-committer.asciidoc', + translations: ['de', 'zh'], + renderArticles: true + }, + { + learning_path_group: 'Contributor', + dirName: 'contributor', + workbook: '04-contributor.asciidoc', + translations: ['ja', 'zh'], + renderArticles: true + }, + { + learning_path_group: 'Product Owner', + dirName: 'product-owner', + workbook: '03-product-owner.asciidoc', + translations: [], + renderArticles: false + }, + ] mkdirSync('./learningpath') -sections.forEach(({ learning_path_group, dirName, workbook, translations, renderArticles }) => { - const baseReadPath = `../${dirName}` - const baseWritePath = `./learningpath/${dirName}` - mkdirSync(baseWritePath) + sections.forEach(({ learning_path_group, dirName, workbook, translations, renderArticles }) => { + const baseReadPath = `../${dirName}` + const baseWritePath = `./learningpath/${dirName}` + mkdirSync(baseWritePath) - translations.concat('' /* The English original */).forEach((translation) => { - const isTranslation = translation !== '' - const writePath = join(baseWritePath, translation) - mkdirSync(writePath) + translations.concat('' /* The English original */).forEach(async (translation) => { + const isTranslation = translation !== '' + const writePath = join(baseWritePath, translation) + mkdirSync(writePath) - const readPath = join(baseReadPath, translation) - const articles = getArticleFiles(readPath) - articles.forEach((article) => { - const articleTitle = article.asciiDoc.match(/== (.*)/)[1] - const articleNumber = article.filePath.split('/').pop().split('-')[0] - const fileName = articleNumber === '01' ? `${writePath}/index.md` : `${writePath}/${articleNumber}.md` - const frontMatter = { - layout: 'learning-path-page', - show_meta: false, - title: `Learning Path - ${learning_path_group} - ${articleTitle}`, - learning_path_article: renderArticles ? article.filePath.replace('../', '') : undefined, - learning_path_group, - learning_path_menu_title: `${articleNumber} - ${articleTitle}`, - learning_path_position: parseInt(articleNumber), - learning_path_translation: translation, - no_video: isTranslation // Videos not available translated. - } + const readPath = join(baseReadPath, translation) + const articles = getArticleFiles(readPath) + articles.forEach(async (article) => { + const articleTitle = article.asciiDoc.match(/== (.*)/)[1] + const articleNumber = article.filePath.split('/').pop().split('-')[0] + const fileName = articleNumber === '01' ? `${writePath}/index.md` : `${writePath}/${articleNumber}.md` + const contributors = await getContributors(article.filePath.replace('../', '')) + const frontMatter = { + layout: 'learning-path-page', + show_meta: false, + title: `Learning Path - ${learning_path_group} - ${articleTitle}`, + learning_path_article: renderArticles ? article.filePath.replace('../', '') : undefined, + learning_path_group, + learning_path_menu_title: `${articleNumber} - ${articleTitle}`, + learning_path_position: parseInt(articleNumber), + learning_path_translation: translation, + no_video: isTranslation, // Videos not available translated. + contributors + } - writeMarkdownFile(fileName, frontMatter) - }) + writeMarkdownFile(fileName, frontMatter) + }) - // Workbooks not translated. - if (!isTranslation) { - const workbookFileName = `${writePath}/workbook.md` - console.log('workbookFileName', workbookFileName) - const workbookFrontMatter = { - layout: 'learning-path-page', - show_meta: false, - title: `Learning Path - ${learning_path_group} - Workbook`, - learning_path_article: `workbook/${workbook}`, - learning_path_group, - learning_path_menu_title: `${learning_path_group} Workbook`, - learning_path_position: articles.length - articles.filter(Array.isArray).length + 1, - learning_path_translation: translation, - no_video: true - } + // Workbooks not translated. + if (!isTranslation) { + const workbookFileName = `${writePath}/workbook.md` + const contributors = await getContributors(`workbook/${workbook}`) + console.log('workbookFileName', workbookFileName) + const workbookFrontMatter = { + layout: 'learning-path-page', + show_meta: false, + title: `Learning Path - ${learning_path_group} - Workbook`, + learning_path_article: `workbook/${workbook}`, + learning_path_group, + learning_path_menu_title: `${learning_path_group} Workbook`, + learning_path_position: articles.length - articles.filter(Array.isArray).length + 1, + learning_path_translation: translation, + no_video: true, + contributors + } - writeMarkdownFile(workbookFileName, workbookFrontMatter) - } + writeMarkdownFile(workbookFileName, workbookFrontMatter) + } + }) }) -}) \ No newline at end of file +})() \ No newline at end of file diff --git a/scripts/get_contributors.js b/scripts/get_contributors.js new file mode 100644 index 00000000..43a07ebd --- /dev/null +++ b/scripts/get_contributors.js @@ -0,0 +1,37 @@ +require('dotenv').config() +const { graphql } = require("@octokit/graphql") + +const graphqlWithAuth = graphql.defaults({ + headers: { + authorization: `token ${process.env.TOKEN}` + } +}) + +module.exports = async function (filepath) { + const contributors = await graphqlWithAuth( + `{ + repository(owner: "InnerSourceCommons", name: "InnerSourceLearningPath") { + object(expression: "master") { + ... on Commit { + history(first: 100, path: "${filepath}") { + totalCount + nodes { + author { + name + } + } + } + } + } + } + }` + ) + + const history = contributors.repository.object.history + + if (history.totalCount > 100) { + throw Error('This script needs updating to handle >100 commits') + } + + return [...new Set(history.nodes.map(node => node.author.name))] +} \ No newline at end of file diff --git a/scripts/package-lock.json b/scripts/package-lock.json index aed0f697..9d57dfb2 100644 --- a/scripts/package-lock.json +++ b/scripts/package-lock.json @@ -4,6 +4,102 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@octokit/endpoint": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.9.tgz", + "integrity": "sha512-3VPLbcCuqji4IFTclNUtGdp9v7g+nspWdiCUbK3+iPMjJCZ6LEhn1ts626bWLOn0GiDb6j+uqGvPpqLnY7pBgw==", + "requires": { + "@octokit/types": "^5.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.5.7.tgz", + "integrity": "sha512-Gk0AR+DcwIK/lK/GX+OQ99UqtenQhcbrhHHfOYlrCQe17ADnX3EKAOKRsAZ9qZvpi5MuwWm/Nm+9aO2kTDSdyA==", + "requires": { + "@octokit/request": "^5.3.0", + "@octokit/types": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request": { + "version": "5.4.10", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.10.tgz", + "integrity": "sha512-egA49HkqEORVGDZGav1mh+VD+7uLgOxtn5oODj6guJk0HCy+YBSYapFkSLFgeYj3Fr18ZULKGURkjyhkAChylw==", + "requires": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.0.0", + "@octokit/types": "^5.0.0", + "deprecation": "^2.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.1", + "once": "^1.4.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.3.tgz", + "integrity": "sha512-GgD5z8Btm301i2zfvJLk/mkhvGCdjQ7wT8xF9ov5noQY8WbKZDH9cOBqXzoeKd1mLr1xH2FwbtGso135zGBgTA==", + "requires": { + "@octokit/types": "^5.0.1", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/types": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-5.5.0.tgz", + "integrity": "sha512-UZ1pErDue6bZNjYOotCNveTXArOMZQFG6hKJfOnGnulVCMcVVi7YIIuuR4WfBhjo7zgpmzn/BkPDnUXtNx+PcQ==", + "requires": { + "@types/node": ">= 8" + } + }, + "@types/node": { + "version": "14.14.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz", + "integrity": "sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw==" + }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, + "dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, "yaml": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", diff --git a/scripts/package.json b/scripts/package.json index 47878207..d436ee54 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -4,6 +4,8 @@ "description": "", "main": "substitute_article_urls.js", "dependencies": { + "@octokit/graphql": "^4.5.7", + "dotenv": "^8.2.0", "yaml": "^1.10.0" }, "devDependencies": {}, From 5d6d077543e559d4c4d811d2c5a393893de5776b Mon Sep 17 00:00:00 2001 From: tanzhongyi <13718272827@163.com> Date: Fri, 6 Nov 2020 21:49:40 +0800 Subject: [PATCH 7/9] add zh translation for product owner (#341) Co-authored-by: tanzhongyi003 <1371827282827@163.com> --- scripts/generate_learning_path_markdown.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/generate_learning_path_markdown.js b/scripts/generate_learning_path_markdown.js index 3fd33f84..3c380586 100644 --- a/scripts/generate_learning_path_markdown.js +++ b/scripts/generate_learning_path_markdown.js @@ -60,8 +60,8 @@ const sections = [ learning_path_group: 'Product Owner', dirName: 'product-owner', workbook: '03-product-owner.asciidoc', - translations: [], - renderArticles: false + translations: ['zh'], + renderArticles: true }, ] @@ -117,4 +117,4 @@ sections.forEach(({ learning_path_group, dirName, workbook, translations, render writeMarkdownFile(workbookFileName, workbookFrontMatter) } }) -}) \ No newline at end of file +}) From e20abc70b63410af0fec31ba8e968e4877039515 Mon Sep 17 00:00:00 2001 From: Tom Sadler Date: Fri, 6 Nov 2020 17:18:48 +0000 Subject: [PATCH 8/9] Inlcude name and URL for contributors --- scripts/get_contributors.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/get_contributors.js b/scripts/get_contributors.js index 43a07ebd..491bc85a 100644 --- a/scripts/get_contributors.js +++ b/scripts/get_contributors.js @@ -18,6 +18,10 @@ module.exports = async function (filepath) { nodes { author { name + user { + name + url + } } } } @@ -33,5 +37,12 @@ module.exports = async function (filepath) { throw Error('This script needs updating to handle >100 commits') } - return [...new Set(history.nodes.map(node => node.author.name))] + return Object.values(history.nodes.reduce((acc, { author }) => { + const name = (author.user && author.user.name) || author.name + acc[name] = { + name, + url: author.user && author.user.url + } + return acc + }, {})) } \ No newline at end of file From 88a16ba4191c39a8420915558b7349fdc1c0af45 Mon Sep 17 00:00:00 2001 From: rrrutledge Date: Mon, 9 Nov 2020 10:23:15 -0800 Subject: [PATCH 9/9] Explanation of how to add subtitles (#344) --- CONTRIBUTING.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7eea3be9..88f66d72 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,6 +24,11 @@ Here is [an example](https://github.com/InnerSourceCommons/InnerSourceLearningPa * Here is the [status of translation efforts](https://github.com/InnerSourceCommons/InnerSourceLearningPath/wiki/Translations). * Other mechanics of working on translations follow the guidelines below that apply to any file in the `InnerSourceLearningPath`. +# Subtitles + +* All videos may have subtitles in any language. +* See [this video](https://drive.google.com/file/d/1IaAH8Zmp2ggBtelexhaZUqia5yS8mUjE/view?usp=sharing) for how to add them. + # Files * When submitting new files, follow the folder structure listed under **Repository Setup** in [the README](./README.md).