<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Lukasz Gornicki</title>
    <description>The latest articles on Forem by Lukasz Gornicki (@derberg).</description>
    <link>https://forem.com/derberg</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F304132%2Fc91c0efa-6145-4c33-ae37-7ae4dc8ca0c5.jpeg</url>
      <title>Forem: Lukasz Gornicki</title>
      <link>https://forem.com/derberg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/derberg"/>
    <language>en</language>
    <item>
      <title>Top 3 harmful incidents in open-source in 2021</title>
      <dc:creator>Lukasz Gornicki</dc:creator>
      <pubDate>Sun, 06 Feb 2022 17:44:55 +0000</pubDate>
      <link>https://forem.com/derberg/top-3-harmful-incidents-in-open-source-in-2021-1mk0</link>
      <guid>https://forem.com/derberg/top-3-harmful-incidents-in-open-source-in-2021-1mk0</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was already published &lt;a href="https://www.brainfart.dev/blog/topbad3oss2021"&gt;in brainfart blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  For starter
&lt;/h2&gt;

&lt;p&gt;I am a full-time open sourcerer by choice. I believe that open-source is the way software should be built, by default. Thus every single crap that happens in open source hurts me personally.&lt;/p&gt;

&lt;p&gt;In this 2021 summary, I will not tackle &lt;a href="https://twitter.com/shitoberfest"&gt;Shitoberfest&lt;/a&gt; and all the hate around &lt;a href="https://hacktoberfest.digitalocean.com/"&gt;Hacktoberfest&lt;/a&gt;, as now it seems to be a regular October shitstorm.&lt;/p&gt;

&lt;p&gt;I think that Shitoberfest initiative is harmful as every radical initiative that sees the world only in black and white colors. That is it. Maybe one day I'll write about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. I don't have time for amateur hour shenanigans
&lt;/h2&gt;

&lt;p&gt;The Tech world is a small world.&lt;/p&gt;

&lt;p&gt;GitHub is not Facebook. You can't just throw shit on people without consequences. Hate speech on GitHub is not easily forgotten; your relations can be easily tracked. If you do not control your emotions, you may become a ghost one day.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FUKXJwPK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uv0xq13u2t9261c7dx8s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FUKXJwPK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uv0xq13u2t9261c7dx8s.png" alt="Image description" width="880" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8Z3JPiaF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aocvkm3pjux8awx0662d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Z3JPiaF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aocvkm3pjux8awx0662d.png" alt="Image description" width="880" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm referring to &lt;a href="https://github.com/GitLabPHP/Client/pull/646"&gt;GitLabPHP Client&lt;/a&gt; related issue. I bet that &lt;a href="https://twitter.com/GrahamJCampbell/status/1396819482732023814"&gt;Graham Campbell&lt;/a&gt; had some bad moments because of it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CvPhhM9p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vmpqjxgjmtf9g4y4mzy4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CvPhhM9p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vmpqjxgjmtf9g4y4mzy4.png" alt="Image description" width="880" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the essence of communication issues on social platforms.&lt;/p&gt;

&lt;p&gt;People forget they interact with real human beings. Like seriously, I bet this guy would never behave like this if he would speak to the maintainer, like face-to-face.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/1GSaf4b1-Qw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Is it really so hard to imagine that written words can harm another human? Even more than the ones you say directly, in private. Written words stay online forever.&lt;/p&gt;

&lt;p&gt;So to summarize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Yes, there can be open-source projects that have a bug&lt;/li&gt;
&lt;li&gt;Yes, there can be open-source projects that have broken tests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just help or leave, don't forget to take your frustrations with you.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Rust moderation team resignation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/rust-lang"&gt;The Rust programming language&lt;/a&gt; is popular and has a large community.&lt;/p&gt;

&lt;p&gt;The larger you get, the more people you need to be actively involved with, especially project moderation. Somebody needs to ensure the code of conduct is followed, and the community is healthy.&lt;/p&gt;

&lt;p&gt;Unfortunately, something went wrong, and &lt;a href="https://github.com/rust-lang/team/pull/671"&gt;the moderation team members resigned&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm not part of the Rust community. For me, this topic is interesting for two reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I'm an open-source fanatic that simply feels sad when some glitches are showing up in open-source communities,&lt;/li&gt;
&lt;li&gt;I'm building community at &lt;a href="https://www.asyncapi.com/"&gt;AsyncAPI&lt;/a&gt; and definitely prefer to learn from the mistakes of others&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, public resignation had to happen for transparency reasons. It was a good call.&lt;/p&gt;

&lt;p&gt;The problem is that they tried to be as polite as possible and transparent at the same time. It only caused more confusion.&lt;/p&gt;

&lt;p&gt;I learned nothing. Provided &lt;a href="https://www.reddit.com/r/rust/comments/qzme1z/moderation_team_resignation/"&gt;Reddit thread&lt;/a&gt; did not help much either.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3xCuQbbB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c9mcszu7pziu2nddyv7u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3xCuQbbB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c9mcszu7pziu2nddyv7u.png" alt="Image description" width="880" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.rust-lang.org/inside-rust/2021/11/25/in-response-to-the-moderation-team-resignation.html"&gt;Official message&lt;/a&gt; from the Rust team appeared 3 days later. Zero details, but at least acknowledgment. In a slow open-source world, pretty fast response.&lt;/p&gt;

&lt;p&gt;About 3 weeks later, we got &lt;a href="https://blog.rust-lang.org/inside-rust/2021/12/17/follow-up-on-the-moderation-issue.html"&gt;more details&lt;/a&gt;, but because of the sensitiveness of the issue, we didn't learn more.&lt;/p&gt;

&lt;p&gt;Sensitive topics require reasonable investigation, I agree. Unfortunately, a lack of transparency leaves many open questions.&lt;/p&gt;

&lt;p&gt;Open questions lead to more discussion and &lt;a href="https://news.ycombinator.com/item?id=29306845"&gt;conspiracy theories&lt;/a&gt;. So you either stand, be transparent and moderate discussion, or censor and let people talk about it elsewhere. I know it only sounds easy, though.&lt;/p&gt;

&lt;p&gt;What feels super weird to me is that the blog post about the issue was actually an email. It was sent a week earlier to project members. There seems to be a clear separation between the community and the Rust project members. It is not my community, I don't know the details, but it sounds super unhealthy that the community learns details a week after Project members. Like members are employees and community a customer.&lt;/p&gt;

&lt;p&gt;Anyway, there is one thing I like in the blog post:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Needless to say, it is difficult to govern an open-source project which has reached a size larger than most companies4 and yet is composed of volunteers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A large and sustainable community can't be built only on the shoulders of individual contributors.&lt;/p&gt;

&lt;p&gt;You always need a hybrid approach, individual and corporate contributors. Model governance to not favor any specific group.&lt;/p&gt;

&lt;p&gt;So to summarize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transparency, transparency, and transparency,&lt;/li&gt;
&lt;li&gt;Doesn't matter if you are an active maintainer or occasional supporter. Every community member has an equal right to know the state of the project at the same time,&lt;/li&gt;
&lt;li&gt;Large communities need lots of regular maintainers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Log4J
&lt;/h2&gt;

&lt;p&gt;Oh yes, the recent tsunami of hate and love.&lt;/p&gt;

&lt;p&gt;Many hope it will shake companies and wake them up from a dream that they can use open-source software for free without consequences.&lt;/p&gt;

&lt;p&gt;I'm not a type of a believer. I don't share these hopes.&lt;/p&gt;

&lt;p&gt;For those that hear about it for the first time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log4J is a Java package for logging&lt;/li&gt;
&lt;li&gt;It is open-source and under Apache Foundation&lt;/li&gt;
&lt;li&gt;Folks found out &lt;a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45046"&gt;large vulnerability issue&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, &lt;a href="https://christine.website/blog/open-source-broken-2021-12-11"&gt;is open-source broken&lt;/a&gt; or &lt;a href="https://nadh.in/blog/open-source-is-not-broken/"&gt;is it not broken&lt;/a&gt;. To be or not to be that is the question.&lt;/p&gt;

&lt;p&gt;All the folks complaining at Log4J maintainers seem to miss a crucial point. Mainly because it is open-source, maintained by people with passion, the issue was solved quickly.&lt;/p&gt;

&lt;p&gt;Also, many people do not understand one thing. The fact that the project is under a foundation doesn't mean it is well funded. This is not the goal of having a project under a foundation.&lt;/p&gt;

&lt;p&gt;You put the project under the foundation to make all these corporations happy, so they do not have to worry about the project license in the long run. People that represent corporations basically admit that they use or plan to use your project for free on a scale. Unfortunately, they do not ask if your rent is due.&lt;/p&gt;

&lt;p&gt;There needs to be a way to finance open-source at scale. Have some global budget or something that distributes money. Maybe existing foundations should adjust their profile and collect more to put money back into the projects under their umbrella.&lt;/p&gt;

&lt;p&gt;Nobody should expect regular engineers to be good at coding and collecting money simultaneously. Going from door to door asking for money is not cool at all.&lt;/p&gt;

&lt;p&gt;Platforms like GitHub and package managers like NPM (in the case of JS ecosystem) should build a kind of alert system. There should be some reporting tool that lists all the projects at risk. There should be a foundation or something that gets money from all tech, asses the risky projects, contact maintainers, and offer help. Yeah, I know, super tricky, but the only way IMHO.&lt;/p&gt;

&lt;p&gt;Don't expect maintainers to beg for money!&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>Is Hacktoberfest Good For Maintainers?</title>
      <dc:creator>Lukasz Gornicki</dc:creator>
      <pubDate>Thu, 05 Nov 2020 13:41:38 +0000</pubDate>
      <link>https://forem.com/derberg/is-hacktoberfest-good-for-maintainers-42i3</link>
      <guid>https://forem.com/derberg/is-hacktoberfest-good-for-maintainers-42i3</guid>
      <description>&lt;h2&gt;
  
  
  tl;dr
&lt;/h2&gt;

&lt;p&gt;In October, we welcomed at AsyncAPI Initiative 26 new contributors with 70 pull requests (PRs) merged. It was an exhausting but also a fascinating experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hacktoberfest Is Ok
&lt;/h2&gt;

&lt;p&gt;Don't be afraid of &lt;a href="https://hacktoberfest.digitalocean.com/"&gt;Hacktoberfest&lt;/a&gt;. It is an excellent event for both contributors and maintainers.&lt;/p&gt;

&lt;p&gt;There are &lt;a href="https://blog.domenic.me/hacktoberfest/"&gt;haters&lt;/a&gt; that will tell you something different. My advice, follow &lt;a href="https://en.wikipedia.org/wiki/Truncated_mean"&gt;truncated mean&lt;/a&gt; measure and always discard extreme opinions, especially if they call for boycotting:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Finally, and most importantly, we can remember that this is how DigitalOcean treats the open source maintainer community, and stay away from their products going forward&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cancel culture at its best. The fact that someone is good at programming or works at Google or Facebook doesn't make them experts in everything. Remember that celebrities are not good candidates for a role model.&lt;/p&gt;

&lt;p&gt;There are no perfect events; there are no best solutions. There is always a place for improvement, but it should be followed by open, civilized discussion.&lt;/p&gt;

&lt;p&gt;Let me conclude by saying that I hope the "harm to the open source made by DigitalOcean" is not as significant as the harm that such hate does to open source by discouraging new open-source contributors. However, this is just speculation. How can I consider any of these things harmful if I did not conduct scientific research? I can only confirm that Hacktoberfest did not harm &lt;a href="https://www.asyncapi.com/"&gt;AsyncAPI Initiative&lt;/a&gt;. On the contrary, it was pretty neat.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spam
&lt;/h2&gt;

&lt;p&gt;During the entire event, we had only two spam PRs. I can imagine that a much more popular and known project might have had more. Nevertheless, adding the &lt;strong&gt;invalid&lt;/strong&gt; label and closing a PR is a super simple operation, three clicks.&lt;/p&gt;

&lt;p&gt;The definition of spam heavily depends on maintainers. For example, &lt;a href="https://github.com/facebook/react/pull/19953"&gt;this&lt;/a&gt; is not invalid to me, because I don't think of grammar as "subjective nits".&lt;/p&gt;

&lt;h2&gt;
  
  
  Why We Participated in Hacktoberfest
&lt;/h2&gt;

&lt;p&gt;Our intentions were pretty clear from the very beginning. As I wrote in the &lt;a href="https://www.asyncapi.com/blog/hacktoberfest-2020"&gt;previous post&lt;/a&gt;, we wanted to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Promote &lt;a href="https://www.asyncapi.com/"&gt;AsyncAPI Initiative&lt;/a&gt; as a place where we work not only on the AsyncAPI specification, but also lots of tools&lt;/li&gt;
&lt;li&gt;Help members of the broader open-source community make their first contributions in a friendly environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My impression is that sometimes the open-source is perceived as a kind of elite gathering. &lt;strong&gt;This is quite often blocking people from joining because they feel they cannot help but rather waste others' time.&lt;/strong&gt; I was there in the past, I thought the same. It's just another variation of the damn &lt;a href="https://en.wikipedia.org/wiki/Impostor_syndrome"&gt;impostor syndrome&lt;/a&gt;. You can always help, no matter what your experience is.&lt;/p&gt;

&lt;p&gt;Start small. Don't start with tasks that can be overwhelming. Don't throw yourself into the deep end. &lt;/p&gt;

&lt;p&gt;We wanted to help others make first baby steps in a secure and inclusive environment, with lots of patience and support.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Takes To Have 70 PRs Merged
&lt;/h2&gt;

&lt;p&gt;It is not enough to label 70 issues with the &lt;strong&gt;hacktoberfest&lt;/strong&gt; label, sorry 😃&lt;/p&gt;

&lt;p&gt;First of all, you need to be passionate about open source and dedicated to what you do. It can't just be a task that somebody assigned to you. It would help if you were prepared to treat Hacktoberfest participants as a priority. I would compare it to the onboarding process of new hires. &lt;/p&gt;

&lt;p&gt;Of course, not all participants join to stay longer, usually they just follow the  "one pull request, and I'm out of here" approach.&lt;/p&gt;

&lt;p&gt;It doesn't matter. &lt;/p&gt;

&lt;p&gt;Please don't make assumptions; assumptions are evil. Be opened, treat every contribution equally, and remember that the onboarding process is a crucial element. If you fail with the onboarding process, you fail big time at the very beginning.&lt;/p&gt;

&lt;h3&gt;
  
  
  What We Prepared
&lt;/h3&gt;

&lt;p&gt;We prepared the following materials for potential participants:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.asyncapi.com/blog/hacktoberfest-2020"&gt;Blog post&lt;/a&gt; about our participation&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/playlist?list=PLbi1gRlP7pigFSE_6G88x0t12HFLU4A4b"&gt;Onboarding videos&lt;/a&gt; that explain how to start&lt;/li&gt;
&lt;li&gt;78 issues from more than 30 repositories and put them all in one &lt;a href="https://docs.google.com/spreadsheets/d/1vX4J395apexutfQ0OSqPNltFKDacmemHZwCmOXwHNLo/"&gt;list&lt;/a&gt; with additional information about the difficulty level or the technical area,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It took me around eight workdays to do it all. The most time-consuming part was to go through all the issues, pick candidates, create new ones, and group them all in a Google Sheet.&lt;/p&gt;

&lt;h3&gt;
  
  
  What We Did During The Event
&lt;/h3&gt;

&lt;p&gt;70 pull requests mean —at least— 70 reviews 😅&lt;/p&gt;

&lt;p&gt;If you know your project well, it is not very time-consuming, and anyway, it is the work you have to do as a maintainer. I do not count this time as an extra Hacktoberfest effort. Of course, it can be overwhelming if this is not a standard amount of PRs that you get every month.&lt;/p&gt;

&lt;p&gt;We also hosted &lt;a href="https://www.youtube.com/playlist?list=PLbi1gRlP7pigZP2da6zbDT2YU7glQOTPH"&gt;office hours&lt;/a&gt; for participants. This was fun, and we wanted to start doing live streams about AsyncAPI anyway.&lt;/p&gt;

&lt;p&gt;Last but not least, once a week, I advertised our project on the official Hacktoberfest Discord server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/asyncapi/vscode-extension/pull/8#issuecomment-719759737"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HZ0-FeJ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/veu7w53e3l8ltnfht67o.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It looks like we do not need to do more for the next year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was It Worth It
&lt;/h2&gt;

&lt;p&gt;Hell yeah, and I'm already looking forward to Hacktoberfest 2021.&lt;/p&gt;

&lt;p&gt;It was great to see so many different people interacting with the project and seeing we reached our goal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/asyncapi/html-template/pull/98#issuecomment-709014754"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4t-a7D67--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wwhbphy1d75csqro5o3i.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We got some new features, CI/CD cleanup in all repositories, and solved many trivial SonarCloud-reported issues that we would never found time to solve.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Made It Such a Success
&lt;/h2&gt;

&lt;p&gt;Our success was a typical return on investment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/asyncapi/playground/pull/38#issuecomment-710014222"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---ifXj68R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0weu3bjf31sv4n1ok6hv.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We asked all contributors to provide feedback on how they learned about us and what was the most helpful resource. 20 out of 26 responded to our request.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CAR7aVi6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bmtd4i58py5c6999rjo9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CAR7aVi6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bmtd4i58py5c6999rjo9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figure 1: Ways in which the contributors learned about AsyncAPI participating in Hacktoberfest&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I think it is pretty clear that introducing the official Discord channel was a great idea. I personally do not like Discord because of the lack of support for threads, but better this than nothing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qvP6PHeU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7xqzpfbnw3l1pf0rfd9y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qvP6PHeU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7xqzpfbnw3l1pf0rfd9y.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figure 2: Resources helpful for contributors&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Such a simple thing as a Google Sheet with a list of issues grouped by different factors was, in the end, our best resource for contributors. I encourage you to create such a sheet for your contributors next year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Request to Hacktoberfest Organizers
&lt;/h2&gt;

&lt;p&gt;There is one thing that calls for an improvement for next year. Just one? Yeah, opt-in solution for projects that want to participate in Hacktoberfest was addressed during this event, and I assume it stays on.&lt;/p&gt;

&lt;p&gt;The number of projects that people can work on is overwhelming, and finding the right issue seems very difficult. Please have a look at the feedback we got from our contributors. It is enough to develop an official application where potential contributors can adequately filter out issues by technology and difficulty. In the end, it doesn't make sense for all maintainers to work on their own Google Sheets and post it on Discord. A better way would be to introduce an app for all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hall Of Fame
&lt;/h2&gt;

&lt;p&gt;Below you can find a list of all contributors that joined AsyncAPI during Hacktoberfest and contributed their time to the project. The list is sorted alphabetically, including the number of PRs created by this contributor.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/ab510"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CEtCapCD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/46869762%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            ab510 (2)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/anbreaker"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--85DjvN25--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/6112820%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            anbreaker (3)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/beni0888"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5rnrsw_D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/2619784%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Jesús Miguel Benito Calzada (1)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/bszwarc"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uh-WHiAt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/17266942%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
             Barbara Szwarc (8)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/bufutda"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ro6uqSu6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/7246741%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Mitchell Sawatzky (2)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/C-Zekeri"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G7pbtwZr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/55132738%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Chenemi Zekeri (2)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/charlietharas"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P8XIlQqh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/55163594%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Charlie Tharas (1)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/christeen24"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QMDB8ZY0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/26082656%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Christeen Fernando (1)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/DanielChuDC"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m-gxwRXq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/52316624%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            danielchu (4)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/depimomo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xChORFpO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/12368942%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            depimomo (4)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/falconmfm"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r-65t2a4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/2099350%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Miguel Angel Falcón Muñoz (1)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/gabrielclaudino"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B-JDJEVK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/26636890%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Gabriel Claudino (1)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/HashTalmiz"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_VD7cPWG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/55018280%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Talmiz Ahmed (5)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/HUTCHHUTCHHUTCH"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nfka5n2w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/55915170%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            HUTCHHUTCHHUTCH (11)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/JakubIwanowski"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d1Leqtbh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/25127286%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Jakub Iwanowski (2)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/jooaodanieel"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BrpRQyr7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/12701604%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            João Francisco Lino Daniel (1)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/juergenbr"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EN28G4XF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/683438%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Jürgen B. (3)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/mbeuil"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Nx-DaJN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/33709157%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            mbeuil (2)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/mowies"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I7ozPFzJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/6901203%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Moritz Wiesinger (1)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/nekosune"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i86FmPUW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/690546%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Katrina Knight (2)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/Orodan"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b7rct00o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/7422824%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Jimmy Kasprzak (3)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/philrussel21"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OMJTWBpz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/44673258%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Phil Antiporda (1)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/RageZBla"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r5Q8K7EW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/1196871%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Olivier Lechevalier (6)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/sanskar-p"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z-DW-BfQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/54014518%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
             Sanskar Patro (1)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/sharkham"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qyO0-9rZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/49769979%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
            Sam (1)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="https://github.com/slavakr"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OHCZMktz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/1413160%3Fv%3D4" width="100px;" alt=""&gt;
        &lt;br&gt;
        
          &lt;b&gt;
             GrimPix (1)
          &lt;/b&gt;
        
      &lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Cover photo by &lt;a href="https://unsplash.com/@goian?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Ian Schneider&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/success-event?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>hacktoberfest</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Join AsyncAPI @Hacktoberfest and Make Your First Contribution in a Friendly Environment</title>
      <dc:creator>Lukasz Gornicki</dc:creator>
      <pubDate>Thu, 01 Oct 2020 07:27:01 +0000</pubDate>
      <link>https://forem.com/derberg/join-asyncapi-hacktoberfest-and-make-your-first-contribution-in-a-friendly-environment-1kgc</link>
      <guid>https://forem.com/derberg/join-asyncapi-hacktoberfest-and-make-your-first-contribution-in-a-friendly-environment-1kgc</guid>
      <description>&lt;h2&gt;
  
  
  What is AsyncAPI
&lt;/h2&gt;

&lt;p&gt;AsyncAPI is a specification for describing your &lt;a href="https://www.asyncapi.com/docs/getting-started/event-driven-architectures/"&gt;event-driven architecture&lt;/a&gt;. You are probably using already &lt;a href="https://www.asyncapi.com/docs/getting-started/coming-from-openapi/"&gt;OpenAPI/Swagger specification&lt;/a&gt; for describing your synchronous RESTful APIs. AsyncAPI is something that supplements OpenAPI. When you should use AsyncAPI, one of the cases is when your services do not talk to each other directly but through a message broker.&lt;/p&gt;

&lt;p&gt;In contrast to the OpenAPI Initiative, AsyncAPI Initiative is focused not only on creating and evolving the AsyncAPI specification but also on its tooling. It is a vendor-neutral space for the community to work together on the spec and its tools. We work on tools like specification parsers or docs and code generators.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/pU71J-F7pfI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Hacktoberfest And Why AsyncAPI Initiative Joins It
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://hacktoberfest.digitalocean.com/"&gt;Hacktoberfest&lt;/a&gt; is a well-known event that promotes open source contributions. In short, you have the entire October to submit four pull requests to any project you want, and in exchange, you get a super cool t-shirt. Is that it? Is it just for a t-shirt? Nah, the t-shirt is nice but what you also get is easy access to open source world. Maintainers of many projects open up for contributions, and it is a great chance to make your first step to joining this fantastic world.&lt;/p&gt;

&lt;p&gt;AsyncAPI Initiative joins the Hacktoberfest for two main reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Promote AsyncAPI Initiative as a place where we don't work on the specification only but also build a lot of great tools&lt;/li&gt;
&lt;li&gt;Make it much easier for the community to make the first contribution to one of the AsyncAPI repositories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the past, we were also there where you are now, shy and uncertain if we can impact open source community. We want to give you an easy path to take the first baby steps in the world of open source in a welcoming and friendly environment.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/_1WRr3Ml9t4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can You Help
&lt;/h2&gt;

&lt;p&gt;There is always a lot of work waiting out there. For the sake of this special event, we prepared around 75 GitHub issues that you can pick up. They represent different areas (for example, JavaScript or HTML), different difficulty (for example, 50 issues are easy), and different repositories. No matter if they are trivial or demanding, all of them are important for us. Even with trivial ones, where you, for example, need to remove a semicolon, we will still be super happy if you do this work because this will improve the quality of the project (SonarCloud reports). In other words, every single issue from &lt;a href="https://docs.google.com/spreadsheets/d/1vX4J395apexutfQ0OSqPNltFKDacmemHZwCmOXwHNLo/edit?usp=sharing"&gt;this&lt;/a&gt; list is important.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Pick The Right Issue
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.google.com/spreadsheets/d/1vX4J395apexutfQ0OSqPNltFKDacmemHZwCmOXwHNLo/edit?usp=sharing"&gt;Here&lt;/a&gt; you can find a list of all the issues that you can work on. Most of the issues are about code contribution, but not all of them. There are also issues about documentation or CI/CD configuration (we use GitHub Actions). Just pick the issues you want to work on, one at a time, and let us know in the comments section that you want to work on it.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Iqs_2BiNEEo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Setup Your Environment and Create a First Pull Request
&lt;/h3&gt;

&lt;p&gt;Once you &lt;a href="https://git-scm.com/book/en/v2/Getting-Started-Installing-Git"&gt;install Git&lt;/a&gt; on your machine and get a &lt;a href="https://github.com/join"&gt;GitHub account&lt;/a&gt;, you need first to decide if you are here just for Hacktoberfest or longer, and make sure if your issue is easy and maybe you can complete it in the GitHub UI. &lt;/p&gt;

&lt;p&gt;In case you are here just for the Hacktoberfest, and you picked easy issues that involve changes only to a single file, there is no need to install Git and complicate your life. GitHub UI enables you to &lt;a href="https://docs.github.com/en/free-pro-team@latest/github/managing-files-in-a-repository/editing-files-in-your-repository"&gt;make changes to a single file online&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In case you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;want to stay with us longer,&lt;/li&gt;
&lt;li&gt;you picked up an issue where you need to make changes to more than just one file,&lt;/li&gt;
&lt;li&gt;you also need to run the project locally to check if it works&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then follow &lt;a href="https://github.com/asyncapi/.github/blob/master/git-workflow.md"&gt;this&lt;/a&gt; short instruction on how to fork the repository and set it up locally.&lt;/p&gt;

&lt;p&gt;Once you are ready with your changes, submit a pull request. Be nice and follow our &lt;a href="https://github.com/asyncapi/.github/blob/master/CODE_OF_CONDUCT.md"&gt;code of conduct&lt;/a&gt; and make sure your pull request is &lt;a href="https://github.com/asyncapi/.github/blob/master/CONTRIBUTING.md#conventional-commits"&gt;described properly&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/BsC5tu4M1rw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Office Hours
&lt;/h2&gt;

&lt;p&gt;Do you feel overwhelmed? No need. You can do it. Just take this blog post seriously. &lt;/p&gt;

&lt;p&gt;Trust me when I write that every pull request is crucial for us.&lt;br&gt;
Trust me when I write that we are a welcoming community.&lt;br&gt;
Don't be afraid that you will waste our time. If we would think about it this way, we would not even join the Hacktoberfest.&lt;/p&gt;

&lt;p&gt;Still not sure if you can make it? Don't worry. We want to host office hours throughout the event, 2x a week, 1h long, and different timezones. You can join whenever you want and ask us anything, or do pair programming with us. We start with the first meeting on &lt;a href="https://calendar.google.com/calendar/u/0?cid=dGJyYmZxNGRlNWJjbmd0OG9rdmV2NGxzdGtAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ"&gt;Tuesday 6th, 8AM UTC&lt;/a&gt; and then on the following days:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tuesday 6th, 8AM UTC&lt;/li&gt;
&lt;li&gt;Thursday 8th, 4PM UTC&lt;/li&gt;
&lt;li&gt;Tuesday 13th, 8AM UTC&lt;/li&gt;
&lt;li&gt;Thursday 15th, 4PM UTC&lt;/li&gt;
&lt;li&gt;Tuesday 20th, 8AM UTC&lt;/li&gt;
&lt;li&gt;Thursday 22nd, 4PM UTC&lt;/li&gt;
&lt;li&gt;Tuesday 27th, 8AM UTC&lt;/li&gt;
&lt;li&gt;Thursday 29th, 4PM UTC&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also join us in a more asynchronous discussion on &lt;a href="https://www.asyncapi.com/slack-invite/"&gt;Slack&lt;/a&gt;. For updates and latest news, the best is to follow our &lt;a href="https://twitter.com/AsyncAPISpec"&gt;Twitter account&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Enjoy the Hacktoberfest!&lt;/p&gt;
&lt;h2&gt;
  
  
  Blooper Reel
&lt;/h2&gt;

&lt;p&gt;Before you jump to your first contribution, have a look a the making of the videos. It was quite fun.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/anjcF2l0lGs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>opensource</category>
      <category>codenewbie</category>
      <category>contributorswanted</category>
    </item>
    <item>
      <title>Analyse Sentiments In Issues and PRs And Get Notified</title>
      <dc:creator>Lukasz Gornicki</dc:creator>
      <pubDate>Thu, 17 Sep 2020 17:51:27 +0000</pubDate>
      <link>https://forem.com/derberg/analyse-sentiments-in-issues-and-prs-and-get-notified-52dc</link>
      <guid>https://forem.com/derberg/analyse-sentiments-in-issues-and-prs-and-get-notified-52dc</guid>
      <description>&lt;h3&gt;
  
  
  My Workflow
&lt;/h3&gt;

&lt;p&gt;I created an action named &lt;a href="https://github.com/marketplace/actions/code-of-conduct-compliance-through-sentiments-analysis"&gt;Code of conduct compliance through sentiments analysis&lt;/a&gt; and want to use it in a workflow with Slack integration in the &lt;a href="https://www.asyncapi.com/"&gt;AsyncAPI Initiative&lt;/a&gt;. I'm a maintainer and community guardian in this project and want to make sure that people respect each other when working in the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Submission Category: Maintainer Must-Haves
&lt;/h3&gt;

&lt;p&gt;Cause you want to keep your community healthy and know when people disrespect each other.&lt;/p&gt;

&lt;h3&gt;
  
  
  Yaml File and Link to Code
&lt;/h3&gt;

&lt;p&gt;The most basic example of using this action with other actions is when you want to send the information about negative sentiments to some communicator. Below example shows how to use this action with another action for sending messages to Slack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Sentiment&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;analysis'&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
  &lt;span class="na"&gt;issue_comment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;created&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;edited&lt;/span&gt;
  &lt;span class="na"&gt;issues&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;opened&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;edited&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;opened&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;edited&lt;/span&gt;
  &lt;span class="na"&gt;pull_request_review&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;submitted&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;edited&lt;/span&gt;
  &lt;span class="na"&gt;pull_request_review_comment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;created&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;edited&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checking sentiments&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check sentiment&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;derberg/code-of-conduct-sentiment-analysis-github-action@v1&lt;/span&gt;
        &lt;span class="c1"&gt;# id is needed for a step if you want to access its output in another step&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sentiments&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="c1"&gt;# you can find an instruction on how to setup Google project with access to Natural Language API here https://github.com/BogDAAAMN/copy-sentiment-analysis#gcp_key-get-your-gcp-api-key&lt;/span&gt;
          &lt;span class="na"&gt;gcp_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GCP_KEY }}&lt;/span&gt; 
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;someimportantcompany/github-actions-slack-message@v1&lt;/span&gt;
        &lt;span class="c1"&gt;# this step runs only if sentiment is a negative numner&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.sentiments.outputs.sentiment &amp;lt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="c1"&gt;# to get a webhook url of your channel use this documentation https://slack.com/intl/en-pl/help/articles/115005265063-Incoming-webhooks-for-Slack&lt;/span&gt;
          &lt;span class="c1"&gt;# first register new app here (https://api.slack.com/apps&lt;/span&gt;
          &lt;span class="na"&gt;webhook-url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SLACK_WEBHOOK_URL }}&lt;/span&gt;
          &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Here ${{steps.sentiments.outputs.source}} you can find a potential negative text that requires your attention as the sentiment analysis score is ${{steps.sentiments.outputs.sentiment}}&lt;/span&gt;
          &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;orange&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This is what you see in Slack once the negative sentiment is spotted:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6_1tO-le--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7rbxcp82dx1a7mopqhgy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6_1tO-le--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7rbxcp82dx1a7mopqhgy.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not using Slack? then check different actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/marketplace/actions/discord-message-notify"&gt;Discord integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/marketplace/actions/send-email"&gt;Send an email&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are plenty of different notifications-like actions that you can use. Check &lt;a href="https://github.com/sdras/awesome-actions/blob/master/README.md#notifications-and-messages"&gt;this&lt;/a&gt; awesome list.&lt;/p&gt;

&lt;p&gt;The rest of the examples of using the action are stored in the readme of the GitHub Action.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/derberg"&gt;
        derberg
      &lt;/a&gt; / &lt;a href="https://github.com/derberg/code-of-conduct-sentiment-analysis-github-action"&gt;
        code-of-conduct-sentiment-analysis-github-action
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Use this action to analyze sentiments in issues and pull request to identify negative emotions that need to be checked against the Code of Conduct
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Code of Conduct Compliance Through Sentiments Analysis&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://raw.githubusercontent.com/derberg/code-of-conduct-sentiment-analysis-github-action/master/#overview"&gt;Overview&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/derberg/code-of-conduct-sentiment-analysis-github-action/master/#why-this-action-requires-other-actions"&gt;Why this action requires other actions?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/derberg/code-of-conduct-sentiment-analysis-github-action/master/#how-sentiments-are-analized"&gt;How sentiments are analized&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://raw.githubusercontent.com/derberg/code-of-conduct-sentiment-analysis-github-action/master/#examples"&gt;Examples&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/derberg/code-of-conduct-sentiment-analysis-github-action/master/#basic-example-using-afinn-wordlist"&gt;Basic example using AFINN wordlist&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/derberg/code-of-conduct-sentiment-analysis-github-action/master/#basic-example-using-google-natural-language-api"&gt;Basic example using Google Natural Language API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/derberg/code-of-conduct-sentiment-analysis-github-action/master/#example-using-google-api-and-slack-action"&gt;Example using Google API and Slack action&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/derberg/code-of-conduct-sentiment-analysis-github-action/master/#troubleshooting"&gt;Troubleshooting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/derberg/code-of-conduct-sentiment-analysis-github-action/master/#development"&gt;Development&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Overview&lt;/h2&gt;
&lt;p&gt;Use this action to analyze sentiments in issues and pull requests to identify emotions that need to be checked against the Code of Conduct
This action only analyzes sentiments. Alone it is not very useful as it is just able to log the sentiment on GitHub Actions log level. It is intended to be used with other Github Actions.
An example use case could be run this action and then send the results to Slack with another action.&lt;/p&gt;
&lt;h3&gt;
Why this action requires other actions?&lt;/h3&gt;
&lt;p&gt;It is because it "only" analyzes the sentiment, but it is up to you to decide in the workflow setup the negative sentiment for you…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/derberg/code-of-conduct-sentiment-analysis-github-action"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;This action can analyze sentiments using two different solutions: built-in and 3rd party. Out of the box, this action is integrated with &lt;a href="https://www.npmjs.com/package/sentiment"&gt;sentiment&lt;/a&gt; package to do analytics based on &lt;a href="http://www2.imm.dtu.dk/pubdb/pubs/6010-full.html"&gt;AFINN&lt;/a&gt; wordlist. Instead of such basic analytics, better use this action to communicate with &lt;a href="https://cloud.google.com/natural-language/docs/basics"&gt;Google Natural Language API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Google API is &lt;a href="https://cloud.google.com/natural-language/pricing"&gt;not expensive&lt;/a&gt;. It is free up to 5k requests and 1$ up to 1m requests. I recommend this way instead of the dictionary check. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cover photo by &lt;a href="https://unsplash.com/@grakozy?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Greg Rakozy&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/stars?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>actionshackathon</category>
      <category>githubactions</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Convert Swagger 2.0 to OpenAPI 3.0</title>
      <dc:creator>Lukasz Gornicki</dc:creator>
      <pubDate>Tue, 18 Aug 2020 13:09:34 +0000</pubDate>
      <link>https://forem.com/derberg/convert-swagger-2-0-to-openapi-3-0-3joj</link>
      <guid>https://forem.com/derberg/convert-swagger-2-0-to-openapi-3-0-3joj</guid>
      <description>&lt;p&gt;Staying with Swagger 2.0 is like staying with ... still working on a good comparison. Anyway, you should migrate to OpenAPI, and my goal here is not to convince you why. I assume you already made this smart decision, and I just want to make it easier for you.&lt;/p&gt;

&lt;p&gt;I did not perform any more in-depth investigation of available tools. There are &lt;a href="https://github.com/Mermade/oas-kit" rel="noopener noreferrer"&gt;tools&lt;/a&gt; provided by Mermade Software. To be more specific, by &lt;a href="https://twitter.com/PermittedSoc" rel="noopener noreferrer"&gt;Mike Ralphson&lt;/a&gt; that is a member of &lt;a href="https://github.com/OAI/OpenAPI-Specification/blob/master/MAINTAINERS.md" rel="noopener noreferrer"&gt;Technical Steering Committee&lt;/a&gt;. For me, this is a good reason not to research different tools.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Convert in a Browser&lt;/li&gt;
&lt;li&gt;
Convert in a Terminal

&lt;ul&gt;
&lt;li&gt;NPM&lt;/li&gt;
&lt;li&gt;NPX&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Convert Multiple Files&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Convert in a Browser
&lt;/h2&gt;

&lt;p&gt;Conversion in a browser is addressed by &lt;a href="https://twitter.com/kinlane" rel="noopener noreferrer"&gt;Kin Lane&lt;/a&gt; aka API Evangelist in &lt;a href="https://twitter.com/apievangelist/status/1295502093625643008" rel="noopener noreferrer"&gt;this thread and the video&lt;/a&gt; so watch it and go to &lt;a href="https://mermade.org.uk/openapi-converter" rel="noopener noreferrer"&gt;https://mermade.org.uk/openapi-converter&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Convert in a Terminal
&lt;/h2&gt;

&lt;p&gt;Use &lt;a href="https://github.com/Mermade/oas-kit/blob/master/packages/swagger2openapi/README.md" rel="noopener noreferrer"&gt;swagger2openapi&lt;/a&gt; and have fun:&lt;/p&gt;

&lt;h3&gt;
  
  
  NPM
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Install the tool &lt;code&gt;npm install -g swagger2openapi&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run conversion &lt;code&gt;swagger2openapi --yaml --outfile openapi.yaml https://petstore.swagger.io/v2/swagger.json&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And that is it. Check your new &lt;code&gt;openapi.yaml&lt;/code&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  NPX
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/npx" rel="noopener noreferrer"&gt;NPX&lt;/a&gt; is useful in CI/CD where you do not want to install &lt;code&gt;swagger2openapi&lt;/code&gt; globally.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx -p swagger2openapi swagger2openapi --yaml --outfile openapi.yaml https://petstore.swagger.io/v2/swagger.json&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker
&lt;/h3&gt;

&lt;p&gt;NPM and NPX is not your thingy? use the Docker image provided by Mike.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;#this part "-v ${PWD}:/usr/src/app" mounts the directory where you started "docker run" inside the container where CLI is triggered, this way generated "openapi.yaml" gets into your local drive&lt;/span&gt;
docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PWD&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;:/usr/src/app mermade/swagger2openapi swagger2openapi &lt;span class="nt"&gt;--yaml&lt;/span&gt; &lt;span class="nt"&gt;--outfile&lt;/span&gt; openapi.yaml https://petstore.swagger.io/v2/swagger.json


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Convert Multiple Files
&lt;/h2&gt;

&lt;p&gt;You most probably have many services, and you need to convert many Swagger files, and you do not want to do it one by one but all at once with a script. You can use Bash and write some script that runs the CLI, but writing Bash scripts is like ... yeah, one day I'll find a good comparison.&lt;/p&gt;

&lt;p&gt;Just use &lt;code&gt;swagger2openapi&lt;/code&gt; as a library. Go to &lt;a href="https://github.com/derberg/convert-swagger-to-openapi-playground#convert-multiple-files" rel="noopener noreferrer"&gt;this&lt;/a&gt; repository and try out the sample project that converts multiple files located in directories and subdirectories.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/derberg" rel="noopener noreferrer"&gt;
        derberg
      &lt;/a&gt; / &lt;a href="https://github.com/derberg/convert-swagger-to-openapi-playground" rel="noopener noreferrer"&gt;
        convert-swagger-to-openapi-playground
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Some instructions and sample how to convert Swagger 2.0 files to OpenAPI 3.0
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Convert Swagger to OpenAPI Playground&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Staying with Swagger 2.0 is like staying with ... still working on a good comparison. Anyway, you should migrate to OpenAPI, and my goal here is not to convince you why. I assume you already made this smart decision, and I just want to make it easier for you.&lt;/p&gt;

&lt;p&gt;I did not perform any more in-depth investigation of available tools. There are &lt;a href="https://github.com/Mermade/oas-kit" rel="noopener noreferrer"&gt;tools&lt;/a&gt; provided by Mermade Software. To be more specific, by &lt;a href="https://twitter.com/PermittedSoc" rel="nofollow noopener noreferrer"&gt;Mike Ralphson&lt;/a&gt; that is a member of &lt;a href="https://github.com/OAI/OpenAPI-Specification/blob/master/MAINTAINERS.md" rel="noopener noreferrer"&gt;Technical Steering Committee&lt;/a&gt;. For me, this is a good reason not to research different tools.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/derberg/convert-swagger-to-openapi-playground#convert-in-a-browser" rel="noopener noreferrer"&gt;Convert in a Browser&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/derberg/convert-swagger-to-openapi-playground#convert-in-a-terminal" rel="noopener noreferrer"&gt;Convert in a Terminal&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/derberg/convert-swagger-to-openapi-playground#npm" rel="noopener noreferrer"&gt;NPM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/derberg/convert-swagger-to-openapi-playground#npx" rel="noopener noreferrer"&gt;NPX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/derberg/convert-swagger-to-openapi-playground#docker" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/derberg/convert-swagger-to-openapi-playground#convert-multiple-files" rel="noopener noreferrer"&gt;Convert Multiple Files&lt;/a&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Convert in a Browser&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Conversion in a browser is addressed by &lt;a href="https://twitter.com/kinlane" rel="nofollow noopener noreferrer"&gt;Kin Lane&lt;/a&gt; aka API Evangelist in &lt;a href="https://twitter.com/apievangelist/status/1295502093625643008" rel="nofollow noopener noreferrer"&gt;this thread and the video&lt;/a&gt; so watch it and go to &lt;a href="https://mermade.org.uk/openapi-converter" rel="nofollow noopener noreferrer"&gt;https://mermade.org.uk/openapi-converter&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Convert in a Terminal&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Use &lt;a href="https://github.com/Mermade/oas-kit/blob/master/packages/swagger2openapi/README.md" rel="noopener noreferrer"&gt;swagger2openapi&lt;/a&gt; and…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/derberg/convert-swagger-to-openapi-playground" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>openapi</category>
      <category>javascript</category>
      <category>swagger</category>
    </item>
    <item>
      <title>(Part 2) Full automation of release with GitHub Actions and Conventional Commits for non-JS projects</title>
      <dc:creator>Lukasz Gornicki</dc:creator>
      <pubDate>Tue, 14 Apr 2020 15:01:33 +0000</pubDate>
      <link>https://forem.com/derberg/part-2-full-automation-of-release-with-github-actions-and-conventional-commits-for-non-js-projects-9an</link>
      <guid>https://forem.com/derberg/part-2-full-automation-of-release-with-github-actions-and-conventional-commits-for-non-js-projects-9an</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;tl;dr&lt;br&gt;
&lt;a href="https://dev.to/blog/automated-releases/"&gt;Here&lt;/a&gt; you can find the first blog post about automated releasing. The purpose of this blog post is to show how you can do the same automation in non-JavaScript projects. Even if JavaScript community created tooling, you can still use it in other projects and don't freak out.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This post and the &lt;a href="https://dev.to/blog/automated-releases/"&gt;previous one&lt;/a&gt; come from our experience we gained when working on full automation for all tools maintained by &lt;a href="https://github.com/asyncapi/asyncapi/"&gt;AsyncaPI Initiative&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/asyncapi/asyncapi/"&gt;AsyncAPI&lt;/a&gt; is a specification that you use to create machine-readable definitions of your event-driven APIs. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The previous post focused on JavaScript as the first library that we automated was our &lt;a href="https://github.com/asyncapi/generator/"&gt;generator&lt;/a&gt;. It covered publishing to NPM and usage of the JavaScript community ecosystem. Now we have automation rolled out to all our libraries, Go-written too.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I need to automate release?
&lt;/h2&gt;

&lt;p&gt;To automate a release efficiently, you need two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Machine-readable information that allows you to identify if a given commit should trigger a release or not.&lt;/li&gt;
&lt;li&gt;Tooling that you can easily plug in and configure without the need to write everything from scratch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This automation is possible thanks to the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;Conventional Commits&lt;/a&gt; specification. The purpose of Conventional Commits is to make commits machine-readable but also human-readable. It defines a set of commit prefixes that can be easily parsed and analyzed by tooling and looks good to the human eye too.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://github.com/semantic-release/semantic-release"&gt;Semantic Release&lt;/a&gt; package and related plugins that support Conventional Commits and publishing to different channels like GitHub, NPM, Slack, and others.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where's the catch?
&lt;/h2&gt;

&lt;p&gt;This blog post is about the automation of releases for non-JavaScript projects. Let me be honest though, solutions I mentioned in the previous chapter come from the JavaScript community.&lt;/p&gt;

&lt;p&gt;The problem is, there are people who &lt;a href="https://www.reddit.com/r/javascript/comments/9pwzpn/why_do_people_hate_javascript/"&gt;Hate JavaScript&lt;/a&gt;, they truly &lt;a href="https://www.quora.com/Why-is-JavaScript-so-hated"&gt;hate it&lt;/a&gt; like it is a living thing. Although, I'm personally proud to be an idiot that has a programming language that I can use.&lt;/p&gt;

&lt;p&gt;Conventional Commits specification is heavily inspired by &lt;a href="https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#commit-message-format"&gt;Angular Commit Guidelines&lt;/a&gt;. The Semantic Release package and its plugins ecosystem are all Node.js packages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/10FHR5A4cXqVrO/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/10FHR5A4cXqVrO/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have Java or Go project, you can still use these tools. You do not have to keep &lt;code&gt;package.json&lt;/code&gt; in your repository, so don't worry, you can keep your repository clean. The great folks from Semantic Release thought about you too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/QynGWwS6GdOMj6cvmz/giphy-downsized.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/QynGWwS6GdOMj6cvmz/giphy-downsized.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Semantic Release with GitHub Action in Go project
&lt;/h2&gt;

&lt;p&gt;One of the projects where we use this JavaScript tools is our parser for AsyncAPI documents. It is a &lt;a href="https://github.com/asyncapi/parser-go"&gt;Go parser&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Semantic Release configuration
&lt;/h3&gt;

&lt;p&gt;The Semantic Release package supports configuration files in different formats and file types. You are not bound to &lt;code&gt;package.json&lt;/code&gt;. We chose to use &lt;code&gt;.releaserc&lt;/code&gt; file in YAML format but there are &lt;a href="https://github.com/semantic-release/semantic-release/blob/master/docs/usage/configuration.md#configuration-file"&gt;other options&lt;/a&gt; too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
&lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@semantic-release/commit-analyzer"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;preset&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;conventionalcommits&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@semantic-release/release-notes-generator"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;preset&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;conventionalcommits&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@semantic-release/github"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;assets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-parser.darwin.amd64&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Binary - Darwin AMD64&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-parser.linux.amd64&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Binary - Linux AMD64&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-parser.windows.amd64.exe&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Binary - Windows AMD64&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Our configuration uses plugins to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Analyze Git commits with Conventional Commits specification.&lt;/li&gt;
&lt;li&gt;Create a Git tag and generate changelog for release notes.&lt;/li&gt;
&lt;li&gt;Publish a release with additional assets. We compile our parser as binaries that are compatible with many platforms and we want to have them easily accessible with each release.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We place the configuration under &lt;code&gt;.github/workflows/&lt;/code&gt;, next to our GitHub Action release workflow file: &lt;code&gt;release.yml&lt;/code&gt;. It indicates that it is for release only, nothing else.&lt;/p&gt;

&lt;h3&gt;
  
  
  Release workflow
&lt;/h3&gt;

&lt;p&gt;Let us have a look at the differences between this workflow and the workflow I described for a typical JavaScript project &lt;a href="https://dev.to/blog/automated-releases/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, you define a &lt;code&gt;test&lt;/code&gt; job with the Go environment to trigger tests with different versions of Go.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Testing'&lt;/span&gt;
  &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
  &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;go&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.14'&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.13'&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.12'&lt;/span&gt; 
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repo&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Go&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-go@v1.1.2&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;go-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;matrix.go&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Invoking go test&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;go test ./...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The next step is the &lt;code&gt;release&lt;/code&gt; job, where you can differentiate two core steps. The first part is the generation of the binaries that you want to expose in the GitHub release.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Go&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-go@v1.1.2&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;go-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.14'&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Invoking go vet and binaries generation&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;go vet ./...&lt;/span&gt;
    &lt;span class="s"&gt;GOOS=darwin GOARCH=amd64 go build -o=.github/workflows/asyncapi-parser.darwin.amd64 ./cmd/api-parser/main.go&lt;/span&gt;
    &lt;span class="s"&gt;GOOS=linux GOARCH=amd64 go build -o=.github/workflows/asyncapi-parser.linux.amd64 ./cmd/api-parser/main.go&lt;/span&gt;
    &lt;span class="s"&gt;GOOS=windows GOARCH=amd64 go build -o=.github/workflows/asyncapi-parser.windows.amd64.exe ./cmd/api-parser/main.go&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So far, it is all Go-related operations. How about the release? For the release, you need to set up a Node.js environment to run Semantic Release. Node.js community has this excellent package, &lt;a href="https://www.npmjs.com/package/npx"&gt;npx&lt;/a&gt;, that allows you to run a package without installing it, and this is what you can do here in the workflow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Node.js&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;13&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Add plugin for conventional commits&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install conventional-changelog-conventionalcommits&lt;/span&gt;
  &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.github/workflows&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Release to GitHub&lt;/span&gt;
  &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.github/workflows&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GH_TOKEN }}&lt;/span&gt;
    &lt;span class="na"&gt;GIT_AUTHOR_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-bot&lt;/span&gt;
    &lt;span class="na"&gt;GIT_AUTHOR_EMAIL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;info@asyncapi.io&lt;/span&gt;
    &lt;span class="na"&gt;GIT_COMMITTER_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-bot&lt;/span&gt;
    &lt;span class="na"&gt;GIT_COMMITTER_EMAIL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;info@asyncapi.io&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx semantic-release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You only have to install &lt;code&gt;conventional-changelog-conventionalcommits&lt;/code&gt; explicitly if you want to use &lt;code&gt;conventionalcommits&lt;/code&gt; preset when analyzing Git commits and generating the changelog:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plugins:
- - "@semantic-release/commit-analyzer"
  - preset: conventionalcommits
- - "@semantic-release/release-notes-generator"
  - preset: conventionalcommits
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Take a look at full release workflow for reference:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Release&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Testing'&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;go&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.14'&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.13'&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.12'&lt;/span&gt; 
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repo&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Go&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-go@v1.1.2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;go-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;matrix.go&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Invoking go test&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;go test ./...&lt;/span&gt;

  &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Release&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;GitHub'&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repo&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Go&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-go@v1.1.2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;go-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.14'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Invoking go vet and binaries generation&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;go vet ./...&lt;/span&gt;
          &lt;span class="s"&gt;GOOS=darwin GOARCH=amd64 go build -o=.github/workflows/asyncapi-parser.darwin.amd64 ./cmd/api-parser/main.go&lt;/span&gt;
          &lt;span class="s"&gt;GOOS=linux GOARCH=amd64 go build -o=.github/workflows/asyncapi-parser.linux.amd64 ./cmd/api-parser/main.go&lt;/span&gt;
          &lt;span class="s"&gt;GOOS=windows GOARCH=amd64 go build -o=.github/workflows/asyncapi-parser.windows.amd64.exe ./cmd/api-parser/main.go&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;13&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Add plugin for conventional commits&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install conventional-changelog-conventionalcommits&lt;/span&gt;
        &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.github/workflows&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Release to GitHub&lt;/span&gt;
        &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.github/workflows&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GH_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;GIT_AUTHOR_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-bot&lt;/span&gt;
          &lt;span class="na"&gt;GIT_AUTHOR_EMAIL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;info@asyncapi.io&lt;/span&gt;
          &lt;span class="na"&gt;GIT_COMMITTER_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-bot&lt;/span&gt;
          &lt;span class="na"&gt;GIT_COMMITTER_EMAIL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;info@asyncapi.io&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx semantic-release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You see, you can still have your project "clean" from any JavaScript-specific files and references. Everything you need for running your release with the JavaScript community tooling is only in the release-related configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I don't think I can ever understand this "hate" towards JavaScript. I think, though, that you can "hate" the language, but if you see some amazing tooling built with it, that can increase your productivity, grit your teeth, put bias aside, and enjoy life. Especially, if in exchange you get this excellent feature, notification about release under the Issue and Pull Request:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5gheJtOW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ruy5or83xxwzy3z6jc3u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5gheJtOW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ruy5or83xxwzy3z6jc3u.png" alt="pr info about release"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In case you want to have more explanation on the release automation subject, I recommend reading &lt;a href="https://dev.to/blog/automated-releases/"&gt;the first part of the automation story&lt;/a&gt;. You can also &lt;a href="https://www.asyncapi.com/slack-invite/"&gt;join our Slack&lt;/a&gt; for further discussion.&lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;Cover photo by &lt;a href="https://unsplash.com/@rocknrollmonkey"&gt;Rock'n Roll Monkey&lt;/a&gt; on Unsplash&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This post was originally published at &lt;a href="https://www.asyncapi.com/blog/automated-releases-part-two/"&gt;https://www.asyncapi.com/blog/automated-releases-part-two/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>asyncapi</category>
      <category>github</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>AsyncAPI Conference scheduled for 22.04 - Learn how we did it so you can do it too</title>
      <dc:creator>Lukasz Gornicki</dc:creator>
      <pubDate>Thu, 09 Apr 2020 10:14:52 +0000</pubDate>
      <link>https://forem.com/derberg/asyncapi-conference-scheduled-for-22-04-learn-how-we-did-it-so-you-can-do-it-too-2cg7</link>
      <guid>https://forem.com/derberg/asyncapi-conference-scheduled-for-22-04-learn-how-we-did-it-so-you-can-do-it-too-2cg7</guid>
      <description>&lt;p&gt;It is happening, a first-ever AsyncAPI Online conference. We start on 22 of April, at &lt;a href="https://everytimezone.com/s/52eb2b62"&gt;11 AM UTC&lt;/a&gt;. The event is going to take 7 hours with 12 talks from all over the world. We start in sunny Sydney and finish in cloudy Vancouver. The event is for free, online, in your favorite quarantine room.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/EsCiDSwfAMw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you organize an event like this in such a short time
&lt;/h2&gt;

&lt;p&gt;There are two requirements you should fulfill behind you start organizing a conference:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Gather a few people that like to walk off the beaten tracks. Best would be to involve your whole core team, as we did in AsyncAPI. All three of us got involved 😃

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/fmvilas"&gt;Fran Méndez&lt;/a&gt; - Project Director.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/e_morcillo"&gt;Eva Morcillo Rodríguez&lt;/a&gt; - Marketing and Video Content Manager.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/derberq"&gt;Łukasz Górnicki&lt;/a&gt; - Maintainer and Dev Community Keeper.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Make sure you have a fantastic community behind your back that supports your efforts&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  First baby steps to kick off the event
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Consult your community if what you plan to do makes sense
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6lzigSzE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uai2bckaftw1hyq61iw2.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;li&gt;Set a conference date and call for proposals deadline&lt;/li&gt;
&lt;li&gt;Get your community involved&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We decided on a tight schedule. Our community had only three days to submit proposals. Oh boy, they exceeded our expectations. In total, we got 18! proposals. We were happy and proud but also afraid that we can't accept all talks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Talks selection
&lt;/h2&gt;

&lt;p&gt;We wanted to establish as many fair rules as possible in such a short timeframe. We decided to form a committee of people that could join Fran and vote for talks that they found most interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They could give 1-10 points per talk.&lt;/li&gt;
&lt;li&gt;They had no idea who is behind the talk. They knew only a title and an abstract of every proposal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After voting, we applied the following additional rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We did not accept more than one talk from the same company. We choose the one that was most popular among voters. &lt;/li&gt;
&lt;li&gt;We did not accept talks that were either not related to the theme or other talks accepted for the conference.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, we did not want to favor any company and wanted to have a schedule with talks around a similar area.&lt;/p&gt;

&lt;p&gt;As a result, we accepted &lt;a href="https://www.asyncapiconf.com/#schedule"&gt;11 talks&lt;/a&gt; from the community. We did it thanks to the support of this amazing group of people: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/WaleedAshraf01"&gt;Waleed Ashraf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/PermittedSoc"&gt;Mike Ralphson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jonaslagoni/"&gt;Jonas Lagoni&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/pieroginomicon"&gt;Andrzej Jarzyna&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sponsoring
&lt;/h2&gt;

&lt;p&gt;We decided to &lt;a href="https://github.com/asyncapi/asyncapi/issues/372"&gt;enable companies and individuals&lt;/a&gt; to support the event financially.&lt;/p&gt;

&lt;p&gt;How to collect money? Do it transparently with tools that you already know. We decided to use Open Collective because we use it already to &lt;a href="https://opencollective.com/asyncapi"&gt;collect money for AsyncAPI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We created a dedicated &lt;a href="https://opencollective.com/asyncapi-online-conference-fd574661/"&gt;event&lt;/a&gt; using &lt;a href="https://docs.opencollective.com/help/collectives/events#create-an-event"&gt;Open Collective events&lt;/a&gt;. This approach allows us to collect money and share expenses explicitly for the event only. The sponsors in exchange get much more than just being listed in our &lt;a href="https://www.asyncapiconf.com/#sponsors"&gt;conference sponsors list&lt;/a&gt;, and it is clearly described under our event page.&lt;/p&gt;

&lt;p&gt;What is the money for? We want to spend it mainly on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prizes for the community involved in the event. &lt;/li&gt;
&lt;li&gt;Paid event marketing. We are doing our best to promote event &lt;a href="https://github.com/asyncapi/asyncapi/issues/369"&gt;on our own&lt;/a&gt;, but we know that we could do much better using paid channels too. More people know about the event and indirectly about AsyncAPI, better profits for the community, and the sponsors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Logistics aka connectivity issues can kill your event
&lt;/h2&gt;

&lt;p&gt;These are coronavirus times. ISPs are having stress tests. Netflix is probably hitting view records. Kids are running around the house all the time. We took it all into account, and this is how we want to solve those challenges:&lt;/p&gt;

&lt;p&gt;First of all, we asked our presenters to record their sessions upfront and send them to us. We want to stream them live to YouTube, and we are exploring platforms that might make it easy to stream not only to YouTube but also Twitter and others. Presenters still join their sessions, and they are going to engage with the audience in conference chat in real-time during the whole presentation. What is so great about it?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The audience doesn't have to wait until the end of the presentation with questions as it works in traditional conferences&lt;/li&gt;
&lt;li&gt;Presenters have much more time to engage with their audience, to exchange thoughts, and get more questions. They can also ask their teammates, organization members, or experts in their field to provide support during the talk. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Don't be afraid to organize your event; just find some freaks that follow you to organize it. I'm a proud freak that bought the idea immediately. It is worth it, even if you do not know the outcome yet, the experience you always gain profits in the future.&lt;/p&gt;

&lt;p&gt;In the name of the whole AsyncAPI community and the core team, I'd like to invite you to join our event on 22 of April, at &lt;a href="https://everytimezone.com/s/52eb2b62"&gt;11 AM UTC&lt;/a&gt;. The conference line-up suggests that the AsyncAPI Online conference is going to be epic!&lt;/p&gt;

&lt;p&gt;#stayhome #staysafe #staycurious&lt;/p&gt;

</description>
      <category>asyncapi</category>
      <category>conference</category>
      <category>eventdriven</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Automate AsyncAPI workflows with Github Actions</title>
      <dc:creator>Lukasz Gornicki</dc:creator>
      <pubDate>Fri, 03 Apr 2020 14:52:19 +0000</pubDate>
      <link>https://forem.com/derberg/automate-asyncapi-workflows-with-github-actions-546j</link>
      <guid>https://forem.com/derberg/automate-asyncapi-workflows-with-github-actions-546j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;tl;dr&lt;br&gt;
AsyncAPI community got rich with two GitHub Actions that you can use for &lt;a href="https://github.com/marketplace/actions/asyncapi-github-action"&gt;validation&lt;/a&gt; and &lt;a href="https://github.com/marketplace/actions/generator-for-asyncapi-documents"&gt;generation&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;GitHub organized a &lt;a href="https://githubhackathon.com/#hackathon"&gt;hackathon for GitHub Actions&lt;/a&gt;. There is no better reason to work on a solution if there is a bag of swags waiting for you &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m-AInNqA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://emojis.slackmojis.com/emojis/images/1463602125/429/troll.png" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--m-AInNqA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://emojis.slackmojis.com/emojis/images/1463602125/429/troll.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The hackathon was only a trigger, the right moment to decide that we should engage. The primary motivation was to write a GitHub Action that can help the AsyncAPI community in specification adoption.&lt;/p&gt;

&lt;p&gt;Two AsyncAPI related actions we crafted in March are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our community member, &lt;a href="https://twitter.com/WaleedAshraf01/"&gt;Waleed Ashraf&lt;/a&gt; created &lt;a href="https://github.com/marketplace/actions/asyncapi-github-action"&gt;an action&lt;/a&gt; to validate AsyncAPI documents with our &lt;a href="https://github.com/asyncapi/parser-js/"&gt;parser&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;We also created &lt;a href="https://github.com/marketplace/actions/generator-for-asyncapi-documents"&gt;official AsyncAPI action&lt;/a&gt; for our &lt;a href="https://github.com/asyncapi/generator/"&gt;generator&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Writing a GitHub Action
&lt;/h2&gt;

&lt;p&gt;Our actions are both &lt;a href="https://help.github.com/en/actions/building-actions/creating-a-javascript-action"&gt;written in JavaScript&lt;/a&gt;. The other way of writing action is to do a &lt;a href="https://help.github.com/en/actions/building-actions/creating-a-docker-container-action"&gt;Docker container action&lt;/a&gt;. The best way to start writing your action is to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Follow &lt;a href="https://help.github.com/en/actions/building-actions/creating-a-javascript-action"&gt;this&lt;/a&gt; tutorial to create a simple action to understand its components.&lt;/li&gt;
&lt;li&gt;Get familiar with the &lt;a href="https://github.com/actions/toolkit"&gt;official toolkit&lt;/a&gt; that you can use to simplify writing an action. &lt;/li&gt;
&lt;li&gt;Create your custom action with &lt;a href="https://github.com/actions/javascript-action"&gt;this template&lt;/a&gt; that has many things plugged in already, like eslint, testing, and most important, distro generation, so you do not have to commit &lt;code&gt;node_modules&lt;/code&gt; directory to your repository.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are all the resources I used to write my first action, and to master it, I only had to read the official docs, like the &lt;a href="https://help.github.com/en/actions/building-actions/metadata-syntax-for-github-actions"&gt;reference docs for the "action.yml" file&lt;/a&gt;. Well done GitHub!&lt;/p&gt;

&lt;h2&gt;
  
  
  What I can do today with AsyncAPI GitHub Actions
&lt;/h2&gt;

&lt;p&gt;Those two actions can help you a lot already, together or separately. I present in this post only two possible workflows, and you can take it from here and think about your ideas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validation of AsyncAPI files in a Pull Request
&lt;/h3&gt;

&lt;p&gt;You can make sure that whenever someone makes a Pull Request to propose a change in the AsyncAPI document, you can validate it automatically using &lt;a href="https://twitter.com/WaleedAshraf01/"&gt;Waleed's&lt;/a&gt; action &lt;code&gt;WaleedAshraf/asyncapi-github-action@v0.0.3&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Actions can be triggered by &lt;a href="https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions"&gt;multiple types of events&lt;/a&gt;. In this example, we will trigger the action on any &lt;code&gt;pull_request&lt;/code&gt; event.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Validate AsyncAPI document&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-github-action&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;WaleedAshraf/asyncapi-github-action@v0.0.3&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;filepath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my-directory/asyncapi.yaml'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Generating HTML and publishing it to GitHub Pages
&lt;/h3&gt;

&lt;p&gt;One of the AsyncAPI use cases is to define your application and generate docs out of this definition, best in HTML. The typical workflow here would be to have a GitHub Action that your trigger on every push to the &lt;code&gt;master&lt;/code&gt; branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AsyncAPI documentation publishing&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To generate HTML from your AsyncAPI definition, you need to use &lt;code&gt;asyncapi/github-action-for-generator@v0.2.0&lt;/code&gt; action. You also need to specify a few more things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The template you want to use for generation. In this example, you can see the official &lt;a href="https://github.com/asyncapi/html-template"&gt;AsyncAPI HTML Template&lt;/a&gt;. You can also write your custom template but hosting it on npm is not mandatory.&lt;/li&gt;
&lt;li&gt;Path to the AsyncAPI file, in case it is not in the root of the working directory and its name is not &lt;code&gt;asyncapi.yml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The template specific parameters. The crucial part here is the &lt;code&gt;baseHref&lt;/code&gt; parameter. When enabling &lt;a href="https://pages.github.com/"&gt;GitHub Pages&lt;/a&gt; for a regular repository, the URL of the Web page is &lt;code&gt;https://{GITHUB_PROFILE}.github.io/{REPO_NAME}/&lt;/code&gt;. Specifying &lt;code&gt;baseHref&lt;/code&gt; parameter helps the browser to properly resolve the URLs of relative links to resources like CSS and JS files. You do not have to hardcode the name of the repo in workflow configuration. Your workflow has access to information about the repository it is running in. You could do this: &lt;code&gt;${baseHref=/{github.repository}}/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The output directory where the generator creates files. You might access those files in other steps of the workflow.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generating HTML from my AsyncAPI document&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi/github-action-for-generator@v0.2.0&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;@asyncapi/html-template@0.3.0'&lt;/span&gt;  &lt;span class="c1"&gt;#In case of template from npm, because of @ it must be in quotes&lt;/span&gt;
    &lt;span class="na"&gt;filepath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docs/api/my-asyncapi.yml&lt;/span&gt;
    &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;baseHref=/test-experiment/ sidebarOrganization=byTags&lt;/span&gt; &lt;span class="c1"&gt;#space separated list of key/values&lt;/span&gt;
    &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;generated-html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now you have a trigger and you can generate a Web page. The next step is to publish the generated HTML documentation to GitHub Pages. For this, you can use one of the actions created by the community, like &lt;code&gt;JamesIves/github-pages-deploy-action@3.4.2&lt;/code&gt;. You can also use other hosting solutions than GitHub Pages, like, for example, Netlify and &lt;a href="https://github.com/netlify/actions/tree/master/cli"&gt;one of their actions&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy GH page&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;JamesIves/github-pages-deploy-action@3.4.2&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;ACCESS_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
    &lt;span class="na"&gt;BRANCH&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gh-pages&lt;/span&gt;
    &lt;span class="na"&gt;FOLDER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;generated-html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here is how a full workflow, with embedded validation, could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AsyncAPI documentation publishing&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;generate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;#"standard step" where repo needs to be checked-out first&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repo&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

    &lt;span class="c1"&gt;#Using another action for AsyncAPI for validation&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Validating AsyncAPI document&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;WaleedAshraf/asyncapi-github-action@v0.0.3&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;filepath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docs/api/my-asyncapi.yml&lt;/span&gt;

    &lt;span class="c1"&gt;#In case you do not want to use defaults, you, for example, want to use a different template&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generating HTML from my AsyncAPI document&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi/github-action-for-generator@v0.2.0&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;@asyncapi/html-template@0.3.0'&lt;/span&gt;  &lt;span class="c1"&gt;#In case of template from npm, because of @ it must be in quotes&lt;/span&gt;
        &lt;span class="na"&gt;filepath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docs/api/my-asyncapi.yml&lt;/span&gt;
        &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;baseHref=/test-experiment/ sidebarOrganization=byTags&lt;/span&gt; &lt;span class="c1"&gt;#space separated list of key/values&lt;/span&gt;
        &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;generated-html&lt;/span&gt;

    &lt;span class="c1"&gt;#Using another action that takes generated HTML and pushes it to GH Pages&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy GH page&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;JamesIves/github-pages-deploy-action@3.4.2&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;ACCESS_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
        &lt;span class="na"&gt;BRANCH&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gh-pages&lt;/span&gt;
        &lt;span class="na"&gt;FOLDER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;generated-html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;First of all, huge thank you to &lt;a href="https://twitter.com/WaleedAshraf01/"&gt;Waleed Ashraf&lt;/a&gt; for creating an action to validate AsyncAPI documents.&lt;/p&gt;

&lt;p&gt;Please try out the above-described actions and let us know what you think. Feel free to leave an issue to suggest improvements or ideas for other actions. &lt;/p&gt;

&lt;p&gt;In case you are interested with other GitHub Actions related posts you might have a look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/blog/automated-releases/"&gt;Full automation of release to NPM and Docker Hub with GitHub Actions and Conventional Commits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/derberg/github-actions-when-fascination-turns-into-disappointment-4d75"&gt;GitHub Actions - When Fascination Turns Into Disappointment&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Original blog post published at &lt;a href="https://www.asyncapi.com/blog/asyncapi-github-actions/"&gt;AsyncAPI blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>asyncapi</category>
      <category>githubactions</category>
      <category>github</category>
      <category>githubpages</category>
    </item>
    <item>
      <title>AsyncAPI Online Conference CFP Ends On Friday</title>
      <dc:creator>Lukasz Gornicki</dc:creator>
      <pubDate>Thu, 02 Apr 2020 15:05:44 +0000</pubDate>
      <link>https://forem.com/derberg/asyncapi-online-conference-cfp-ends-tomorrow-59bn</link>
      <guid>https://forem.com/derberg/asyncapi-online-conference-cfp-ends-tomorrow-59bn</guid>
      <description>&lt;p&gt;After reaching &lt;a href="https://github.com/asyncapi/asyncapi/"&gt;1000&lt;/a&gt; ⭐ on GitHub, &lt;a href="https://www.asyncapi.com/"&gt;AsyncAPI Initiative&lt;/a&gt; community decided to go crazy and quickly organize a first, online AsyncAPI conference.&lt;/p&gt;

&lt;p&gt;We just released the &lt;a href="https://www.asyncapiconf.com/"&gt;conference website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can submit your talk proposal using &lt;a href="https://forms.gle/tntZP33tJwPiECKP8"&gt;this&lt;/a&gt; form. &lt;br&gt;
&lt;strong&gt;The deadline is Friday, tomorrow, 03.04.2020&lt;/strong&gt;&lt;br&gt;
We know it is a short time, but the conference is scheduled for 22.04.2020 so not much time left. You do not have to submit a 100% perfect proposal. If we pick you, you will have a chance to prettify it before we publish the agenda next Wednesday.&lt;/p&gt;

&lt;p&gt;Proposals we are looking for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How AsyncAPI helps you&lt;/li&gt;
&lt;li&gt;What products you built thanks to the AsyncAPI&lt;/li&gt;
&lt;li&gt;AsyncAPI use cases&lt;/li&gt;
&lt;li&gt;non-AsyncAPI but still super important for the world of event-driven architectures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;#StayHealthy #StayHome #StayStrong&lt;/p&gt;

</description>
      <category>asyncapi</category>
      <category>conference</category>
      <category>stayhome</category>
      <category>asynchronous</category>
    </item>
    <item>
      <title>Reddit spam filters are blocking dev.to</title>
      <dc:creator>Lukasz Gornicki</dc:creator>
      <pubDate>Fri, 20 Mar 2020 13:56:35 +0000</pubDate>
      <link>https://forem.com/derberg/reddit-spam-filters-are-blocking-dev-to-21ni</link>
      <guid>https://forem.com/derberg/reddit-spam-filters-are-blocking-dev-to-21ni</guid>
      <description>&lt;p&gt;When I started writing on dev.to I tried to promote my work a few times with Reddit as I did in the past with other resources.&lt;/p&gt;

&lt;p&gt;All my posts are always blocked when they have dev.to link, like this one &lt;a href="https://www.reddit.com/r/github/comments/fjjiyn/github_actions_when_fascination_turns_into/"&gt;https://www.reddit.com/r/github/comments/fjjiyn/github_actions_when_fascination_turns_into/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Others, not dev.to related, are fine, like these ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/github/comments/flso7w/full_automation_of_release_to_npm_and_docker_hub/"&gt;https://www.reddit.com/r/github/comments/flso7w/full_automation_of_release_to_npm_and_docker_hub/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/learnjavascript/comments/fltdfo/full_automation_of_release_to_npm_and_docker_hub/"&gt;https://www.reddit.com/r/learnjavascript/comments/fltdfo/full_automation_of_release_to_npm_and_docker_hub/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To me, it seems like whatever comes from dev.to is blocked by Reddit. Is it just me or? What is your experience?&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Full automation of release to NPM and Docker Hub with GitHub Actions and Conventional Commits</title>
      <dc:creator>Lukasz Gornicki</dc:creator>
      <pubDate>Fri, 20 Mar 2020 07:17:31 +0000</pubDate>
      <link>https://forem.com/derberg/full-automation-of-release-to-npm-and-docker-hub-with-github-actions-and-conventional-commits-4fgn</link>
      <guid>https://forem.com/derberg/full-automation-of-release-to-npm-and-docker-hub-with-github-actions-and-conventional-commits-4fgn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;tl;dr&lt;br&gt;
from now on, we release &lt;a href="https://github.com/asyncapi/generator/"&gt;generator&lt;/a&gt; in an automated way. We roll-out this setup to the rest when we see it is needed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Repetitive tasks are tedious. If what you do manually can be automated, then what are you waiting for! &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;But these tasks take only a couple of minutes from time to time, gimme a break&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A couple of minutes here, a couple of minutes there and all of a sudden you do not have time on more important things, on innovation. Automation makes it easier to scale and eliminates errors. Distractions consume time and make you less productive.&lt;/p&gt;

&lt;p&gt;We kick ass at &lt;a href="https://www.asyncapi.com/"&gt;AsyncAPI Initiative&lt;/a&gt; at the moment. We started to improve our tooling regularly. We are now periodically sharing project status in our &lt;a href="https://www.asyncapi.com/subscribe"&gt;newsletter&lt;/a&gt;, and host &lt;a href="https://github.com/asyncapi/asyncapi/issues/115"&gt;bi-weekly open meetings&lt;/a&gt;, but most important is that we just recently updated our roadmap.&lt;/p&gt;

&lt;p&gt;Am I just showing off? It sounds like, but that is not my intention. I wish to point out we are productive, and we want to continue this trend and automation helps here a lot. If you have libraries that you want to release regularly and you plan additional ones to come, you need to focus on release automation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What full automation means
&lt;/h2&gt;

&lt;p&gt;Full automation means that the release process if fully automated with no manual steps. What else did you think?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/6uGhT1O4sxpi8/source.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/6uGhT1O4sxpi8/source.gif" alt="travolta"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your responsibility is just to merge a pull request. The automation handles the rest. &lt;/p&gt;

&lt;p&gt;You might say: &lt;em&gt;but I do not want to release on every merge, sometimes I merge changes that are not related to the functionality of the library&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This is a valid point. You need a way to recognize if the given commit should trigger the release and what kind of version, PATCH, or MINOR. The way to do it is to introduce in your project &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;Conventional Commits&lt;/a&gt; specification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conventional Commits
&lt;/h2&gt;

&lt;p&gt;At &lt;a href="https://www.asyncapi.com/"&gt;AsyncAPI Initiative&lt;/a&gt; we use &lt;a href="https://semver.org/"&gt;Semantic Versioning&lt;/a&gt;. This is why choosing &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;Conventional Commits&lt;/a&gt; specification was a natural decision.&lt;/p&gt;

&lt;p&gt;Purpose of Conventional Commits is to make commits not only human-readable but also machine-readable. It defines a set of commit prefixes that can be easily parsed and analyzed by tooling.&lt;/p&gt;

&lt;p&gt;This is how the version of the library looks like when it follows semantic versioning: &lt;code&gt;MAJOR.MINOR.PATCH&lt;/code&gt;. How does the machine know what release you want to bump because of a given commit? Simplest mapping looks like in the following list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Commit message prefix &lt;code&gt;fix:&lt;/code&gt; indicates &lt;code&gt;PATCH&lt;/code&gt; release,&lt;/li&gt;
&lt;li&gt;Commit message prefix &lt;code&gt;feat:&lt;/code&gt; indicates &lt;code&gt;MINOR&lt;/code&gt; release,&lt;/li&gt;
&lt;li&gt;Commit message prefix &lt;code&gt;{ANY_PREFIX}!:&lt;/code&gt; so for example &lt;code&gt;feat!:&lt;/code&gt; or even &lt;code&gt;refactor!:&lt;/code&gt; indicate &lt;code&gt;MAJOR&lt;/code&gt; release.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It other words, assume your version was 1.0.0, and you made a commit like &lt;code&gt;feat: add a new parameter to test endpoint&lt;/code&gt;. You can have a script that picks up &lt;code&gt;feat:&lt;/code&gt; and triggers release that eventually bumps to version 1.1.0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workflow design
&lt;/h2&gt;

&lt;p&gt;At &lt;a href="https://www.asyncapi.com/"&gt;AsyncAPI Initiative&lt;/a&gt; where we introduced the release pipeline for the very first time, we had to do the following automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tag Git repository with a new version&lt;/li&gt;
&lt;li&gt;Create GitHub Release&lt;/li&gt;
&lt;li&gt;Push new version of the package to &lt;a href="https://www.npmjs.com/"&gt;NPM&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Push new version of Docker image to &lt;a href="https://hub.docker.com/"&gt;Docker Hub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bump the version of the package in &lt;code&gt;package.json&lt;/code&gt; file and commit the change to the repository&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is how the design looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qxKYopGd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/npclfn63htmraj3hcme7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qxKYopGd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/npclfn63htmraj3hcme7.png" alt="npm docker release workflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two workflows designed here. &lt;/p&gt;

&lt;p&gt;The first workflow reacts to changes in the release branch (&lt;code&gt;master&lt;/code&gt; in this case), decides if release should be triggered, and triggers it. The last step of the workflow is a pull request creation with changes in &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;package-lock.json&lt;/code&gt;. Why are changes not committed directly to the release branch? Because we use branch protection rules and do not allow direct commits to release branches.&lt;/p&gt;

&lt;p&gt;You can extend this workflow with additional steps, like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integration testing&lt;/li&gt;
&lt;li&gt;Deployment&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second workflow is just for handling changes in &lt;code&gt;package.json&lt;/code&gt;. To fulfill branch protection settings, we had to auto-approve the pull request so we can automatically merge it.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Actions
&lt;/h2&gt;

&lt;p&gt;Even though I have &lt;a href="https://dev.to/derberg/github-actions-when-fascination-turns-into-disappointment-4d75"&gt;my opinion about GitHub Actions&lt;/a&gt;, I still think it is worth investing in it, especially for the release workflows.&lt;/p&gt;

&lt;p&gt;We used the GitHub-provided actions and the following awesome actions built by the community:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="//ttps://github.com/marketplace/actions/create-pull-request"&gt;Create Pull Request&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/marketplace/actions/auto-approve"&gt;Auto Approve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/marketplace/actions/merge-pull-requests"&gt;Merge Pull Request&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Release workflow
&lt;/h3&gt;

&lt;p&gt;Release workflow triggers every time there is something new happening in the release branch. In our case, it is the &lt;code&gt;master&lt;/code&gt; branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  GitHub and NPM
&lt;/h4&gt;

&lt;p&gt;For releases to GitHub and NPM, the most convenient solution is to integrate &lt;a href="https://github.com/semantic-release/semantic-release"&gt;semantic release&lt;/a&gt; package and related plugins that support Conventional Commits. You can configure plugins in your &lt;code&gt;package.json&lt;/code&gt; in the order they should be invoked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"plugins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"@semantic-release/commit-analyzer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"preset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"conventionalcommits"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"@semantic-release/release-notes-generator"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"preset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"conventionalcommits"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"@semantic-release/npm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"@semantic-release/github"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Conveniently, functional automation uses a &lt;a href="https://www.thinkautomation.com/bots-and-ai/what-are-software-bots/"&gt;technical bot rather than a real user&lt;/a&gt;. GitHub actions allow you to encrypt the credentials of different systems at the repository level. Referring to them in actions looks as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Release to NPM and GitHub&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GH_TOKEN }}&lt;/span&gt;
    &lt;span class="na"&gt;NPM_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NPM_TOKEN }}&lt;/span&gt;
    &lt;span class="na"&gt;GIT_AUTHOR_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-bot&lt;/span&gt;
    &lt;span class="na"&gt;GIT_AUTHOR_EMAIL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;info@asyncapi.io&lt;/span&gt;
    &lt;span class="na"&gt;GIT_COMMITTER_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-bot&lt;/span&gt;
    &lt;span class="na"&gt;GIT_COMMITTER_EMAIL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;info@asyncapi.io&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Aside from automation, the bot also comments on every pull request and issue included in the release notifying subscribed participants that the given topic is part of the release. Isn't it awesome?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lKWU9MWK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iqccywd6s189t5nn8fkk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lKWU9MWK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iqccywd6s189t5nn8fkk.png" alt="pr release indicator"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Docker
&lt;/h4&gt;

&lt;p&gt;For handling Docker, you can use some community-provided GitHub action that abstracts Docker CLI. I don't think it is needed if you know Docker. You might also want to reuse some commands during local development, like image building, and have them behind an npm script like &lt;code&gt;npm run docker-build&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Release to Docker&lt;/span&gt;
  &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.initversion.outputs.version != steps.extractver.outputs.version&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt; 
    &lt;span class="s"&gt;echo ${{secrets.DOCKER_PASSWORD}} | docker login -u ${{secrets.DOCKER_USERNAME}} --password-stdin&lt;/span&gt;
    &lt;span class="s"&gt;npm run docker-build&lt;/span&gt;
    &lt;span class="s"&gt;docker tag asyncapi/generator:latest asyncapi/generator:${{ steps.extractver.outputs.version }}&lt;/span&gt;
    &lt;span class="s"&gt;docker push asyncapi/generator:${{ steps.extractver.outputs.version }}&lt;/span&gt;
    &lt;span class="s"&gt;docker push asyncapi/generator:latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Bump version in package.json
&lt;/h4&gt;

&lt;p&gt;A common practice is to bump the package version in &lt;code&gt;package.json&lt;/code&gt; on every release. You should also push the modified file to the release branch. Be aware though that good practices in the project are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do not commit directly to the release branch. All changes should go through pull requests with proper peer review.&lt;/li&gt;
&lt;li&gt;Branches should have basic protection enabled. There should be simple rules that block pull requests before the merge.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Release workflow, instead of pushing directly to the release branch, should commit to a new branch and create a pull request. Seems like an overhead? No, you can also automate it. Just keep on reading.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create Pull Request with updated package files&lt;/span&gt;
  &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.initversion.outputs.version != steps.extractver.outputs.version&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;peter-evans/create-pull-request@v2.4.4&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GH_TOKEN }}&lt;/span&gt;
    &lt;span class="na"&gt;commit-message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;chore(release):&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.extractver.outputs.version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;
    &lt;span class="na"&gt;committer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-bot &amp;lt;info@asyncapi.io&amp;gt;&lt;/span&gt;
    &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-bot &amp;lt;info@asyncapi.io&amp;gt;&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;chore(release):&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.extractver.outputs.version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;bump&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;in&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;package.json&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;package-lock.json&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;release&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;[${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.extractver.outputs.version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}](https://github.com/${{github.repository}}/releases/tag/v${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.extractver.outputs.version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}})'&lt;/span&gt;
    &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;version-bump/${{ steps.extractver.outputs.version }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Conditions and sharing outputs
&lt;/h4&gt;

&lt;p&gt;GitHub Actions has two excellent features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can set conditions for specific steps&lt;/li&gt;
&lt;li&gt;You can share the output of one step with another&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These features are used in the release workflow to check the version of the package, before and after the GitHub/NPM release step. &lt;/p&gt;

&lt;p&gt;To share the output, you must assign an &lt;code&gt;id&lt;/code&gt; to the step and declare a variable and assign any value to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get version from package.json after release step&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;extractver&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "::set-output name=version::$(npm run get-version --silent)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can access the shared value by the &lt;code&gt;id&lt;/code&gt; and a variable name like &lt;code&gt;steps.extractver.outputs.version&lt;/code&gt;. We use it, for example, in the condition that specifies if further steps of the workflow should be triggered or not. If the version in &lt;code&gt;package.json&lt;/code&gt; changed after GitHub and NPM step, this means we should proceed with Docker publishing and pull request creation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.initversion.outputs.version != steps.extractver.outputs.version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Full workflow
&lt;/h4&gt;

&lt;p&gt;Below you can find the entire workflow file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Release&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Release&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;NPM,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;GitHub,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Docker'&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repo&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;13&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get version from package.json before release step&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;initversion&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "::set-output name=version::$(npm run get-version --silent)"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Release to NPM and GitHub&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GH_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;NPM_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NPM_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;GIT_AUTHOR_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-bot&lt;/span&gt;
          &lt;span class="na"&gt;GIT_AUTHOR_EMAIL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;info@asyncapi.io&lt;/span&gt;
          &lt;span class="na"&gt;GIT_COMMITTER_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-bot&lt;/span&gt;
          &lt;span class="na"&gt;GIT_COMMITTER_EMAIL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;info@asyncapi.io&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run release&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get version from package.json after release step&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;extractver&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "::set-output name=version::$(npm run get-version --silent)"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Release to Docker&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.initversion.outputs.version != steps.extractver.outputs.version&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt; 
          &lt;span class="s"&gt;echo ${{secrets.DOCKER_PASSWORD}} | docker login -u ${{secrets.DOCKER_USERNAME}} --password-stdin&lt;/span&gt;
          &lt;span class="s"&gt;npm run docker-build&lt;/span&gt;
          &lt;span class="s"&gt;docker tag asyncapi/generator:latest asyncapi/generator:${{ steps.extractver.outputs.version }}&lt;/span&gt;
          &lt;span class="s"&gt;docker push asyncapi/generator:${{ steps.extractver.outputs.version }}&lt;/span&gt;
          &lt;span class="s"&gt;docker push asyncapi/generator:latest&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create Pull Request with updated package files&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.initversion.outputs.version != steps.extractver.outputs.version&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;peter-evans/create-pull-request@v2.4.4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GH_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;commit-message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;chore(release):&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.extractver.outputs.version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;
          &lt;span class="na"&gt;committer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-bot &amp;lt;info@asyncapi.io&amp;gt;&lt;/span&gt;
          &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-bot &amp;lt;info@asyncapi.io&amp;gt;&lt;/span&gt;
          &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;chore(release):&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.extractver.outputs.version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;
          &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;bump&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;in&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;package.json&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;package-lock.json&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;release&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;[${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.extractver.outputs.version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}](https://github.com/${{github.repository}}/releases/tag/v${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.extractver.outputs.version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}})'&lt;/span&gt;
          &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;version-bump/${{ steps.extractver.outputs.version }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Automated merging workflow
&lt;/h2&gt;

&lt;p&gt;You may be asking yourself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Why automated approving and merging is handled in a separate workflow and not as part of release workflow&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One reason is that the time between pull request creation and its readiness to be merged is hard to define. Pull requests always include some automated checks, like testing, linting, and others. These are long-running checks. You should not make such an asynchronous step a part of your synchronous release workflow. &lt;/p&gt;

&lt;p&gt;Another reason is that you can also extend such an automated merging flow to handle not only pull requests coming from the release-handling bot but also other bots, that, for example, update your dependencies for security reasons. &lt;/p&gt;

&lt;p&gt;You should divide automation into separate jobs that enable you to define their dependencies. There is no point to run the &lt;strong&gt;automerge&lt;/strong&gt; job until the &lt;strong&gt;autoapprove&lt;/strong&gt; one ends. GitHub Actions allows you to express this with &lt;code&gt;needs: [autoapprove]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Below you can find the entire workflow file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Automerge release bump PR&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;labeled&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;unlabeled&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;synchronize&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;opened&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;edited&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ready_for_review&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;reopened&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;unlocked&lt;/span&gt;
  &lt;span class="na"&gt;pull_request_review&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;submitted&lt;/span&gt;
  &lt;span class="na"&gt;check_suite&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;completed&lt;/span&gt;
  &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

  &lt;span class="na"&gt;autoapprove&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Autoapproving&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hmarr/auto-approve-action@v2.0.0&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.actor == 'asyncapi-bot'&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;github-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secrets.GITHUB_TOKEN&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;

  &lt;span class="na"&gt;automerge&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;autoapprove&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Automerging&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pascalgn/automerge-action@v0.7.5&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.actor == 'asyncapi-bot'&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secrets.GH_TOKEN&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
          &lt;span class="na"&gt;GITHUB_LOGIN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asyncapi-bot&lt;/span&gt;
          &lt;span class="na"&gt;MERGE_LABELS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
          &lt;span class="na"&gt;MERGE_METHOD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;squash"&lt;/span&gt;
          &lt;span class="na"&gt;MERGE_COMMIT_MESSAGE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pull-request-title"&lt;/span&gt;
          &lt;span class="na"&gt;MERGE_RETRIES&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10"&lt;/span&gt;
          &lt;span class="na"&gt;MERGE_RETRY_SLEEP&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10000"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For a detailed reference, you can look into &lt;a href="https://github.com/asyncapi/generator/pull/242"&gt;this pull request&lt;/a&gt; that introduces the above-described workflow in the &lt;a href="https://github.com/asyncapi/generator/"&gt;generator&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Automate all the things, don't waste time. Automate releases, even if you are a purist that for years followed a rule of using &lt;a href="https://chris.beams.io/posts/git-commit/#imperative"&gt;imperative mood&lt;/a&gt; in commit subject and now, after looking on prefixes from Conventional Commits you feel pure disgust.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/8PmTor9XVnD3sxXHRe/source.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/8PmTor9XVnD3sxXHRe/source.gif" alt="disqust"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the end, you can always use something different, custom approach, like reacting to merges from pull requests with the specific label only. If you have time to reinvent the wheel, go for it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/10640GYyK1INZ6/source.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/10640GYyK1INZ6/source.gif" alt="reinvent wheel"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;Cover photo by &lt;a href="https://unsplash.com/@franckinjapan"&gt;Franck V.&lt;/a&gt; taken from Unsplash.&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://www.asyncapi.com/blog/automated-releases/"&gt;https://www.asyncapi.com/blog/automated-releases/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>github</category>
      <category>docker</category>
    </item>
    <item>
      <title>GitHub Actions - When Fascination Turns Into Disappointment</title>
      <dc:creator>Lukasz Gornicki</dc:creator>
      <pubDate>Mon, 16 Mar 2020 08:24:39 +0000</pubDate>
      <link>https://forem.com/derberg/github-actions-when-fascination-turns-into-disappointment-4d75</link>
      <guid>https://forem.com/derberg/github-actions-when-fascination-turns-into-disappointment-4d75</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Looks like this blog post is not valid anymore. July 2020 GitHub released proper support for forks &lt;a href="https://github.blog/2020-08-03-github-actions-improvements-for-fork-and-pull-request-workflows/" rel="noopener noreferrer"&gt;https://github.blog/2020-08-03-github-actions-improvements-for-fork-and-pull-request-workflows/&lt;/a&gt; which is super awesome!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This post was supposed to be about something totally different. It was supposed to be a post about how easily you can automate workflows in your project using GitHub Actions. It was...but I was in the middle of my task when I planned this post. Now I'm pretty much done and I'm disappointed with GitHub for the very first time.&lt;/p&gt;

&lt;p&gt;GitHub Actions got my ❤️ since it was announced. I could not play with it. I had no use case for it as in my previous project we were bound to a specific CI tool. Then I moved to work on &lt;a href="//asyncapi.com/"&gt;AsyncAPI&lt;/a&gt; and I was super happy to introduce GitHub Actions there.&lt;/p&gt;

&lt;h2&gt;
  
  
  First workflow with GH Actions ❤️
&lt;/h2&gt;

&lt;p&gt;I'm an automation freak. I hate to do the same things twice, and that is why the first thing I wanted to improve was Docker image publishing.&lt;/p&gt;

&lt;p&gt;Oh man, I loved it. Starting with GitHub Actions was so easy. Googling out basics was super simple. They also have this super awesome UI for noobs that just started with Actions. Even editing of the workflow files looks different then with other files. There is a dedicated view for workflows with fancy autocomplete and linting. Well done GitHub, well done!!! Using GitHub is as awesome as using TravisCI, but without leaving GitHub UI. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffwzv0hgv35ktoiksijne.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffwzv0hgv35ktoiksijne.png" alt="github workflow edit"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can imagine that with such a level of excitement when I've learned about &lt;a href="https://githubhackathon.com/" rel="noopener noreferrer"&gt;GitHub Actions Hackathon&lt;/a&gt; I was like "Hell yeah, I'd love to participate".&lt;/p&gt;

&lt;p&gt;Now I'm puzzled and lost my motivation to participate in the hackathon. Why? cause I spent some time introducing different workflows and I've learned about some limits that make GitHub Action not as cool as I thought in the beginning.&lt;/p&gt;

&lt;h2&gt;
  
  
  All things GitHub Actions
&lt;/h2&gt;

&lt;p&gt;After my first task with GitHub Actions and a review of &lt;a href="https://github.com/marketplace?type=actions" rel="noopener noreferrer"&gt;available actions&lt;/a&gt; my statement was clear: &lt;code&gt;all automation must go through GitHub Actions&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What use cases I had in mind?&lt;/p&gt;

&lt;h3&gt;
  
  
  Welcome message
&lt;/h3&gt;

&lt;p&gt;Writing a welcome message to &lt;a href="https://github.com/marketplace/actions/first-interaction" rel="noopener noreferrer"&gt;the first-time contributors&lt;/a&gt; is a very useful feature. You can not only use it to say usual &lt;code&gt;Hi&lt;/code&gt; but also to share important links with new joiners. In the case of AsyncAPI, I wanted to make sure we welcome them with a link to a page that explains all the different ways people can interact with &lt;a href="https://github.com/asyncapi/asyncapi/issues/115" rel="noopener noreferrer"&gt;AsyncAPI community&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Auto-labeling
&lt;/h3&gt;

&lt;p&gt;Automated &lt;a href="https://github.com/marketplace/actions/labeler" rel="noopener noreferrer"&gt;labeling of pull requests&lt;/a&gt; depending on what files were modified helps with project maintenance. Not only labeling basing on files modified but also other reasons, like labeling based on the size of the change. It speeds up the maintenance of the project at scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pull request merge
&lt;/h3&gt;

&lt;p&gt;Triggering &lt;a href="https://github.com/marketplace/actions/merge-pull-requests" rel="noopener noreferrer"&gt;pull request merge&lt;/a&gt; with a specific label is a great step to improve the security of your GitHub organization. To be 100% sure you are secure from vulnerabilities (someone left your organization and you forgot to change his access right) and also you're own mistakes, you should not have write access to repositories. Write access should belong only to a bot that can merge pull requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  The moment of 💔
&lt;/h2&gt;

&lt;p&gt;Adding all those different actions was super easy, especially thanks to the awesome community of devs that added so many different GitHub Actions to the marketplace. I tested easily all changes on my fork. I created pull requests in a fork and proved the setup works like a charm.&lt;/p&gt;

&lt;p&gt;Everything was great until I started using them in a real environment. Real environment meaning a project, in an organization that works with contributions through forks like all the other projects on GitHub.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All those workflows are not supported when pull requests come from forks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The reason is that the default &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; used in a fork-workflow &lt;a href="https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token#permissions-for-the-github_token" rel="noopener noreferrer"&gt;has &lt;code&gt;read-only&lt;/code&gt; rights&lt;/a&gt;. You can, of course, provide your own secrets, like &lt;code&gt;MY_GITHUB_TOKEN&lt;/code&gt; but it is pointless effort as &lt;a href="https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#using-encrypted-secrets-in-a-workflow" rel="noopener noreferrer"&gt;custom secrets are not available&lt;/a&gt; in a fork-workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8q2kpk3f7jvs460zcccd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8q2kpk3f7jvs460zcccd.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is like the GitHub team behind the feature never worked in open-source, or their security team is stronger than product management. I don't believe any of these can be true. It is GitHub after all, you kind of trust the brand. I'm truly afraid the reason is &lt;code&gt;money&lt;/code&gt;. On enterprise-level, you almost never work with fork-workflow, so basically those that pay, do not really need strong support for forks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Did we broke up?
&lt;/h2&gt;

&lt;p&gt;There are relationships where you wish to never see your ex again. Not in this case. My heart is broken, I'm disappointed, but I want us to stay friends. I hope this is a temporary issue and that GitHub fixes it, otherwise they will lose a lot on adoption. &lt;/p&gt;

&lt;p&gt;I will still use GitHub Actions for release automation and write about it soon.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Now, come on man, you criticize, you're such a smart ass, but this flow has limits for a reason, this is a real security threat. Someone could fork the repo, modify workflow in the way that he can read the secret and exploit the system secured with it. (&lt;em&gt;a very possible comment that I could get in this post&lt;/em&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a valid point, but very easy to solve with current GitHub functionality. In my previous project, I used &lt;a href="https://github.com/kubernetes/test-infra/tree/master/prow" rel="noopener noreferrer"&gt;Prow&lt;/a&gt; that was built for Kubernetes to test it and maintain the community on a very high scale. Prow also has to support fork-workflow. &lt;/p&gt;

&lt;p&gt;How the Kubernetes test-infra team solved the security concern? They do not trigger CI jobs if the pull request was not created by the member of the organization. Organization member, after checking that the pull request is not modifying GitHub Action workflow, must comment on the pull request to trigger CI with a message like &lt;code&gt;/ok-to-test&lt;/code&gt;. As simple as that.&lt;/p&gt;

&lt;p&gt;GitHub can go a step further here and integrate GitHub Actions with &lt;a href="https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners" rel="noopener noreferrer"&gt;code owners&lt;/a&gt; feature. You should be able to specify in &lt;code&gt;CODEOWNER&lt;/code&gt; file a more limited group of people that can approve changes in workflows and trigger them with &lt;code&gt;/ok-to-test&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I hope that, by accident, I revealed how the GitHub Actions team is already working on fixing this limitation 😃. I really like this functionality and want to also use it for managing and supporting &lt;a href="https://www.asyncapi.com/" rel="noopener noreferrer"&gt;AsyncAPI&lt;/a&gt; community. I'm looking forward to doing all the things with GitHub Actions. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvfmjbwhqm19ys8wbvr3o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvfmjbwhqm19ys8wbvr3o.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>opensource</category>
      <category>beginners</category>
      <category>ci</category>
    </item>
  </channel>
</rss>
