<?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: Sarah Abd</title>
    <description>The latest articles on Forem by Sarah Abd (@sabderemane).</description>
    <link>https://forem.com/sabderemane</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%2F269018%2Fd48f1df9-69ac-43b0-9dc6-4e6e2b6e0ed5.jpg</url>
      <title>Forem: Sarah Abd</title>
      <link>https://forem.com/sabderemane</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sabderemane"/>
    <language>en</language>
    <item>
      <title>TIL: Accessibility resources</title>
      <dc:creator>Sarah Abd</dc:creator>
      <pubDate>Sat, 07 May 2022 10:00:00 +0000</pubDate>
      <link>https://forem.com/sabderemane/til-accessibility-resources-31io</link>
      <guid>https://forem.com/sabderemane/til-accessibility-resources-31io</guid>
      <description>&lt;p&gt;Hi there,&lt;/p&gt;

&lt;p&gt;I decided to start TIL (Today I Learned) series !&lt;/p&gt;

&lt;p&gt;Rodrigo, author of &lt;a href="https://mathspp.com/"&gt;Mathspp&lt;/a&gt; blog, give me envy to do so with his TIL series, as I told him, I will do that to help me to remind me some stuff and share what I discovered to everyone who can be interested on. I’m dedicating my first TIL of a great series to him I hope.&lt;/p&gt;

&lt;p&gt;I started to create a dark mode for Django project and I face to an interesting issue : accessibility.&lt;/p&gt;

&lt;p&gt;This is something I’m aware of, but I discovered I have so many things to learn ! Even my website is really bad for accessibility.. but I learned some ressources very useful which deserve to be written somewhere.&lt;/p&gt;

&lt;p&gt;Accessibility concern many cases : &lt;em&gt;Tritanopia&lt;/em&gt;, &lt;em&gt;Deuteranomaly&lt;/em&gt; and so on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://whocanuse.com/"&gt;Whocanuse&lt;/a&gt;, is based on the same purpose of &lt;a href="https://caniuse.com/"&gt;Caniuse&lt;/a&gt; but for accessibility and contrast.&lt;/p&gt;

&lt;p&gt;It’s really useful to see the simulation of color for each type of vision and contrast with another color. It really helps me to better adjust color contrast.&lt;/p&gt;

&lt;p&gt;Note: you can also see color contrast and ratio in devtools of Chrome :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j71-Sxyx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://sarahabd.com/static/9fbb014ebed953b7d6eaac2309f2d4a4/01e7c/devtools-chrome.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j71-Sxyx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://sarahabd.com/static/9fbb014ebed953b7d6eaac2309f2d4a4/01e7c/devtools-chrome.png" alt="devtools chrome contrast" width="512" height="664"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You also have &lt;a href="https://kontrasto.netlify.app/"&gt;Kontrasto&lt;/a&gt;, created by Thibaud Colas, which have a deep interest in accessibility 🙂&lt;/p&gt;

&lt;p&gt;Really nice to see a way to improve accessibility with images.&lt;/p&gt;

&lt;p&gt;I also discovered &lt;a href="https://webaim.org/resources/linkcontrastchecker/"&gt;Link Contrast Checker&lt;/a&gt; which is a website to see the contrast for links to be sure there are no violation for accessibility.&lt;/p&gt;

&lt;p&gt;I find &lt;a href="https://www.a11yproject.com/checklist/"&gt;accessibility checklist&lt;/a&gt; which can be a good start to make you website more inclusive and see some point you missed.&lt;/p&gt;

&lt;p&gt;As I am a big fan of pipelines, there are also tools to check accessibility with desktop extension or in continuous integration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.deque.com/axe/"&gt;aXe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pa11y.org/"&gt;pa11y&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it for now! I hope it will be useful for someone.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>2021, year in review</title>
      <dc:creator>Sarah Abd</dc:creator>
      <pubDate>Sun, 30 Jan 2022 10:00:00 +0000</pubDate>
      <link>https://forem.com/sabderemane/2021-year-in-review-53oe</link>
      <guid>https://forem.com/sabderemane/2021-year-in-review-53oe</guid>
      <description>&lt;p&gt;Hi there, it's have been a while... First of all, I want to say happy new year to you, best wishes !! &lt;/p&gt;

&lt;p&gt;Thank you to &lt;a href="https://github.com/KatherineMichel"&gt;Katherine Michel&lt;/a&gt; and &lt;a href="https://github.com/dawnwages"&gt;Dawn Wages&lt;/a&gt; for inspiring me to do a Year in Review blog post!&lt;/p&gt;

&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;This year wasn't my best year but I success to do things I can't imagine do. &lt;/p&gt;

&lt;p&gt;My highlights for the year have been: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attending to DjangoCon Europe and US&lt;/li&gt;
&lt;li&gt;Do a lightning talk&lt;/li&gt;
&lt;li&gt;Pass Hacktoberfest challenge&lt;/li&gt;
&lt;li&gt;Make a contribution to a huge project&lt;/li&gt;
&lt;li&gt;Discover and be part of an amazing community&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Learning and improvements
&lt;/h3&gt;

&lt;p&gt;I learn a lot this year, by trying things, reading, and do mistakes of course. I read &lt;a href="https://adamchainz.gumroad.com/l/suydt"&gt;the book of Adams Johnson about testing&lt;/a&gt;, which is really interesting. I discovered I had to change some habits and improve some projects. &lt;/p&gt;

&lt;p&gt;I'm trying to be more involved in things which I care about or I have an interest in, for example, testing or Open Source Software.&lt;/p&gt;

&lt;p&gt;I also learn by interacting with people, even though I still have some difficulty understanding everything in English since I am not fluent but close too!&lt;/p&gt;

&lt;p&gt;I discovered many things in 2021, there are so many resources : newsletter, podcast, twitter accounts (yeah really), let me list some of them :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://anchor.fm/djangogirls"&gt;Django Girls podcast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pycoders.com/"&gt;Pycoder’s weekly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/treyhunner?t=iMH0ONBeIKZmXz2zgiRzkQ&amp;amp;s=09"&gt;Trey hunner&lt;/a&gt; twitter account&lt;/li&gt;
&lt;li&gt;Adams Johnson &lt;a href="https://adamj.eu/books/"&gt;books&lt;/a&gt; and &lt;a href="https://adamj.eu/tech/"&gt;blog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And conferences, even for past years are really interesting. I definitely recommend you to check out!&lt;/p&gt;

&lt;p&gt;I also discovered I can inspire others, even I don't think I did something amazing as other great people of the dev world but you can inspire even on things that don't seem huge. &lt;/p&gt;

&lt;h3&gt;
  
  
  Conferences
&lt;/h3&gt;

&lt;p&gt;I have attend to my first conference, DjangoCon Europe, and gave my first lighting talk ! I have wrote a post &lt;a href="https://sarahabd.com/blog/djangocon-europe-2021-thoughts/"&gt;here&lt;/a&gt;, I hope I will have a chance to attend to the next one. And in real life, so many amazing people have told me that it's a different experience and I really want to see that and see the people I talk to, so many times in the virtual haha. &lt;/p&gt;

&lt;p&gt;I also attend to DjangoCon US, it was very nice but I didn't attend so long due to hours. I wanted to help the organizers but I didn't have time to do so. If you want to contribute to the community, this is a way to do it. Many people think, it's all about code, but there are so many things to do besides coding for contribution. &lt;/p&gt;

&lt;p&gt;I hope I will be able to do more meetups and exchange with people (in real life would be even better!).&lt;/p&gt;

&lt;h3&gt;
  
  
  Hacktoberfest as maintainer
&lt;/h3&gt;

&lt;p&gt;I have done hacktoberfest for the second time, but this time I was contributor and also maintainer, thanks to &lt;a href="https://github.com/funbeedev"&gt;Fum&lt;/a&gt;. This is a great experience, even I didn't imagine how it can be exhausting. As a contributor you want things to happen quickly, but as a maintainer, it’s nice to see the engagement of people but so many things to do and some time people answer like the project is your only life, and I can tell you: this is totally NOT the case ! &lt;/p&gt;

&lt;p&gt;Despite that, I have learned so many things by reviewing: see things in another way, or dig in some subject I didn't know much before.&lt;/p&gt;

&lt;h3&gt;
  
  
  Individuals contributions
&lt;/h3&gt;

&lt;p&gt;I guess this is my best year for contributing to open source, I contributed to many projects. From small contributions to big ones. I contributed to a big project: Django. It was amazing, I also learned while doing it. It's not an impressive contribution, but I hope it will be useful to everyone who uses this amazing framework! I hope to make more contributions, especially in the python ecosystem this new year.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reminder to myself
&lt;/h3&gt;

&lt;p&gt;2021 I tried things I didn't think I would have done. If I have piece of advice to tell, it will be :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be more organized&lt;/li&gt;
&lt;li&gt;Try your best, if it's not perfect, that's fine&lt;/li&gt;
&lt;li&gt;Contribute, help, write. Sometimes you think it's stupid or useless, but it's not for someone else&lt;/li&gt;
&lt;li&gt;Exchange is gold. You can learn things from someone and the person can also learn from you&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>review</category>
      <category>opensource</category>
      <category>django</category>
    </item>
    <item>
      <title>Thoughts on DjangoCon Europe 2021</title>
      <dc:creator>Sarah Abd</dc:creator>
      <pubDate>Mon, 07 Jun 2021 12:00:03 +0000</pubDate>
      <link>https://forem.com/sabderemane/thoughts-on-djangocon-europe-2021-25n1</link>
      <guid>https://forem.com/sabderemane/thoughts-on-djangocon-europe-2021-25n1</guid>
      <description>&lt;p&gt;Hi there, it has been a while since my last post, but I’ m now returning from a great conference: DjangoCon Europe.&lt;/p&gt;

&lt;p&gt;It was my first virtual conference. Thanks to the organizers, it was well done despite the difficult circumstances. We had a &lt;a href="https://gather.town/"&gt;gather.town&lt;/a&gt; to meet people, talks hosted in loudswarm, which worked great! It was very interesting. There were great talks and met amazing people!&lt;/p&gt;

&lt;p&gt;I’m also exhausted lol. I guess it’s another experience as I imagine and due to the return of people who did it in real life. I hope to have the ability to attend to another one in person. As people said, you come for the syntax and stay for the community!&lt;/p&gt;

&lt;p&gt;I gave my first lightning talk at the DjangoCon: “Run Django tests with GitHub Actions” which was a little introduction to GitHub Actions and how to use it with Docker services. I’m completely nervous about things like that but I did it. I’m happy I received some positive feedback. I know also what to improve if I choose to undertake the experience again :)&lt;/p&gt;

&lt;p&gt;If you have one in mind, go for it. You will never regret and it’s a good experience. You will help someone or make someone discover something that you didn’t imagine you could. For the sprints, it was complicated for me to manage the two days, but I was able to be mentor for DjangoGirls on Saturday. It was a good experience for me.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>First contribution to open source, hacktoberfest !</title>
      <dc:creator>Sarah Abd</dc:creator>
      <pubDate>Tue, 03 Nov 2020 09:08:00 +0000</pubDate>
      <link>https://forem.com/sabderemane/first-contribution-to-open-source-hacktoberfest-gif</link>
      <guid>https://forem.com/sabderemane/first-contribution-to-open-source-hacktoberfest-gif</guid>
      <description>&lt;p&gt;First participation, first contribution to open source. Yeah !&lt;/p&gt;

&lt;p&gt;Yes, I finished my first the Hacktoberfest challenge, thanks to Digital Ocean, Dev.to and Intel. If you don’t know what I’m talking about, just check &lt;a href="https://hacktoberfest.digitalocean.com/"&gt;this&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I always wanted to contribute to an open source project. But there always seemed to be obstacles: first thoughts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which project should I choose out of the ocean of possible repositories?&lt;/li&gt;
&lt;li&gt;How can I make a good pull request for a project?&lt;/li&gt;
&lt;li&gt;Issues usually seem to need specific understanding of how the projects develop&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yeah, I know what your are thinking: &lt;em&gt;she might be crazy&lt;/em&gt; or maybe just &lt;em&gt;I feel the same&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I think it’s normal to think whenever you use a good open source project, you want to contribute to it in the future. Open source is incredible. There are so many projects that are used by so many people.&lt;/p&gt;

&lt;p&gt;I have so much respect for open source project maintainers because many or maybe most of our personal or professional projects would fail without them.&lt;/p&gt;

&lt;p&gt;Hacktoberfest is one of the best way to start contributing to open source projects. Their site lists an extensive resources and provides information for contributing regardless of whether you a beginner or a seasoned developer. And if you follow the specific CONTRIBUTING.md for in the open source repository, you can’t be lost (normally).&lt;/p&gt;

&lt;p&gt;Don’t hesitate to reach out to the maintainers or other contributors to ask questions if needed, as well as checking labels, and spending some time carefully reading issues.&lt;/p&gt;

&lt;p&gt;If you’re a beginner you can check start by checking this link which will suggest some good things to get started with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://issuehub.io/?label%5B%5D=good+first+issue"&gt;http://issuehub.io/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if the Hacktoberfest has finished this year, now is still a great time to make your first contributions.&lt;/p&gt;

&lt;p&gt;I contributed to 2 projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&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--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/inspirezonetech"&gt;
        inspirezonetech
      &lt;/a&gt; / &lt;a href="https://github.com/inspirezonetech/TeachMePythonLikeIm5"&gt;
        TeachMePythonLikeIm5
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Teach the Python programming language using a collection of super beginner friendly tutorials and challenges.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&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--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/inspirezonetech"&gt;
        inspirezonetech
      &lt;/a&gt; / &lt;a href="https://github.com/inspirezonetech/TeachMeBashLikeIm5"&gt;
        TeachMeBashLikeIm5
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Teach the Bash programming language using a collection of super beginner friendly tutorials and challenges.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was my first Hacktoberfest event and I have loved this experience. I can’t fully explain but the satisfaction that comes from contributing to something that can be useful to others feels great. It’s also time to discover other projects, by searching or through people who share their experiences and learn new things, of course.&lt;/p&gt;

&lt;p&gt;I will continue to contribute ❤️&lt;/p&gt;

&lt;p&gt;Unfortunately I didn’t officially complete the Hacktoberfest challenge due to an ”&lt;a href="https://github.com/digitalocean/hacktoberfest/issues/724"&gt;intented behaviour&lt;/a&gt;” which now prohibits certain repositories from being eligible.&lt;/p&gt;

&lt;p&gt;So just beware, if you have participated this year and your PRs are still in review, be careful, the flaw can still happen to you. Fum explain all just here.&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/funbeedev" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_-HmArfH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://media.dev.to/cdn-cgi/image/width%3D150%2Cheight%3D150%2Cfit%3Dcover%2Cgravity%3Dauto%2Cformat%3Dauto/https%253A%252F%252Fdev-to-uploads.s3.amazonaws.com%252Fuploads%252Fuser%252Fprofile_image%252F451342%252F369f4c02-4f58-47fe-b818-540afef54704.jpg" alt="funbeedev"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/funbeedev/check-your-hacktoberfest-profile-a-flaw-could-have-reversed-your-completion-of-the-challenge-without-you-knowing-it-2kg6" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;⚠️ Check your Hacktoberfest profile ⚠️ A flaw could have reversed your completion of the challenge without you knowing it&lt;/h2&gt;
      &lt;h3&gt;Fum ・ Nov 7 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#hacktoberfest&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#discuss&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 Regardless this is less important than having first taken the plunge into making contributions to open source projects — which is really the thing at the core of Hacktoberfest.

&lt;p&gt;See you maybe next year!&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Manual trigger with Github Actions</title>
      <dc:creator>Sarah Abd</dc:creator>
      <pubDate>Tue, 28 Jan 2020 15:18:20 +0000</pubDate>
      <link>https://forem.com/sabderemane/manual-trigger-with-github-actions-279e</link>
      <guid>https://forem.com/sabderemane/manual-trigger-with-github-actions-279e</guid>
      <description>&lt;p&gt;Hi there, this blog post explains how to manually trigger builds of GitHub actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why would you want to do that?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Instead of just waiting for a code change or a GitHub workflow change?&lt;/em&gt; Well, for example the last time your build on master ran, maybe some of the servers used by your build were down (example: npm registry, some API you're using for tests, etc..).&lt;/p&gt;

&lt;p&gt;For now &lt;a href="https://github.community/t5/GitHub-Actions/GitHub-Actions-Manual-Trigger-Approvals/td-p/31504"&gt;GitHub says that there's no way to manually trigger a build&lt;/a&gt;, while this question was &lt;a href="https://stackoverflow.com/q/58933155/7087644"&gt;asked on StackOverflow&lt;/a&gt; and some people are even using CURL to trigger manual builds.&lt;/p&gt;

&lt;p&gt;But I have found a better way! With my solution, once you'll have it set up, the ⭐️ button of your GitHub repository will trigger a build every time YOU (and only you) will star the repository. &lt;br&gt;
You can do that as many times as you want.&lt;/p&gt;

&lt;p&gt;Yes, it's a VERY &lt;em&gt;hacky&lt;/em&gt; solution but it works pretty well. ✨&lt;/p&gt;
&lt;h2&gt;
  
  
  How to do manual trigger
&lt;/h2&gt;

&lt;p&gt;Let's dig into it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6oqnfhr50mczsodhp57c.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6oqnfhr50mczsodhp57c.gif" alt="Alt Text" width="" height=""&gt;&lt;/a&gt;&lt;br&gt;
The ⭐️ button is used to launch the workflow if it's possible, like this.&lt;/p&gt;

&lt;p&gt;Update your workflow file to include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;watch&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="nv"&gt;started&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;So the workflow will be executed each time you star, or unstar and star again the repo.&lt;/p&gt;

&lt;p&gt;If we combine that by &lt;a href="https://stackoverflow.com/a/58965362"&gt;a useful advice from Samira&lt;/a&gt; in Stack Overflow, you can launch your workflow only if it's the owner who trigger the action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;github.actor == github.event.repository.owner.login&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;It prevents to execute the action by others and only by maintainers for example.&lt;/p&gt;

&lt;p&gt;Next you can add your job(s) to do and additional services.&lt;/p&gt;

&lt;p&gt;At the end, we have the following workflow...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;Test&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;watch&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="nv"&gt;started&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;build&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;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.actor == github.event.repository.owner.login&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 repository&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;#  add more ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's a starter, so you can adapt it for an existing workflow or start a new one with this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Few notes
&lt;/h2&gt;

&lt;p&gt;There is the possibility to &lt;strong&gt;combine two events&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example you can set your workflow with the watch event and on each push, to have the both ways.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;Test&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;watch&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="nv"&gt;started&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;


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

&lt;/div&gt;



&lt;p&gt;Here it run the process for &lt;strong&gt;each push on master branch and on star of the repo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't forget&lt;/strong&gt; that if you want to re-run a workflow which have failed, &lt;br&gt;
you can re-run all the checks with a UI button set for a failed workflow just like that...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bySr7NRb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/jm4zi3ccyfze9eyndk6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bySr7NRb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/jm4zi3ccyfze9eyndk6g.png" alt="Alt Text" width="800" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It depends on what you really want to do.&lt;/p&gt;

&lt;p&gt;Moreover, you can launch the full workflow with the watch event or only some particular steps if you add a conditional if on a step like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;Test&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;watch&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="nv"&gt;started&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;build&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;Checkout repository&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;Step &lt;/span&gt;&lt;span class="m"&gt;2&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 == github.event.repository.owner.login&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In this case, it will run step 2 only if the repo is starred by the owner.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't forget&lt;/strong&gt; that the ⭐️ button launch the workflow from the default branch (master) only. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notice that there is permissions to avoid actions in the repository or to avoid the third party to run your actions in the settings of the repo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g3reyNza--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/r40qoujp9qt08tz9lmyo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g3reyNza--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/r40qoujp9qt08tz9lmyo.png" alt="Alt Text" width="800" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Suggested by &lt;a href="//dev.to/neilime/comment/nipi"&gt;Emilien in comments&lt;/a&gt;, we can also configure the workflow only for collaborators by creating another job which will be needed to check if it's a collaborator of the project or the workflow will fail.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;authorize&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;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;octokit/request-action@v2.0.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;route&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GET /repos/:repository/collaborators/${{ github.actor }}&lt;/span&gt;
        &lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.repository }}&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.GITHUB_TOKEN }}&lt;/span&gt;

  &lt;span class="na"&gt;build&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;authorize&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="s"&gt;...&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Good to know...
&lt;/h2&gt;

&lt;p&gt;GitHub &lt;em&gt;just&lt;/em&gt; &lt;a href="https://github.blog/changelog/2020-01-27-github-actions-api-beta/"&gt;released their action APIs&lt;/a&gt; which should allow soon either GitHub or browser extensions to add "trigger workflow" buttons on their UI.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1221851549443297280-947" src="https://platform.twitter.com/embed/Tweet.html?id=1221851549443297280"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1221851549443297280-947');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1221851549443297280&amp;amp;theme=dark"
  }



&lt;/p&gt;




&lt;p&gt;I hope you liked this post and special thanks to &lt;a href="//dev.to/vvo"&gt;Vincent&lt;/a&gt; who pushed me to write it :) &lt;/p&gt;

</description>
      <category>github</category>
      <category>actions</category>
      <category>devops</category>
      <category>howto</category>
    </item>
    <item>
      <title>Relation between middle/senior and junior dev</title>
      <dc:creator>Sarah Abd</dc:creator>
      <pubDate>Thu, 09 Jan 2020 19:47:49 +0000</pubDate>
      <link>https://forem.com/sabderemane/relation-between-confirmed-senior-and-junior-dev-1kn</link>
      <guid>https://forem.com/sabderemane/relation-between-confirmed-senior-and-junior-dev-1kn</guid>
      <description>&lt;p&gt;I've been a teacher and also a learner, so I've got something to tell you.&lt;/p&gt;

&lt;p&gt;I've heard so many comments like &lt;em&gt;"you're too junior"&lt;/em&gt;, &lt;em&gt;"you're not a middle/senior dev"&lt;/em&gt;. I'm sure you've heard that too.&lt;/p&gt;

&lt;p&gt;If you told me that something is impossible, I'm the type of woman that will try to succeed even if there is only a small chance.&lt;/p&gt;

&lt;p&gt;Yes, I tried to achieve a proficiency level in tech close to the level of developers who inspired me despite my limited experience.&lt;/p&gt;

&lt;p&gt;The fact is, some people believe that a junior should listen to the middle/senior dev and that's all.&lt;/p&gt;

&lt;p&gt;The middle/senior dev is highly qualified and has experience. For sure.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But it's still &lt;strong&gt;an exchange&lt;/strong&gt;. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sharing knowledge is not easy for everyone. And when you're in this situation, you sometimes have the obligation to explain complexity with simple words and distill abstract ideas into more digestible ones.&lt;/p&gt;

&lt;p&gt;It's an art not a science, really.&lt;/p&gt;

&lt;p&gt;We all know that &lt;strong&gt;a developer is always learning&lt;/strong&gt;, even by asking other devs. Sometimes developers ask things you didn't think about, or you just don't know about, and you also want to know the answer. So sometimes their question prompts you to research more and helps expand your knowledge base.&lt;/p&gt;

&lt;h3&gt;
  
  
  To you the junior dev
&lt;/h3&gt;

&lt;p&gt;Don't think the dev with high skills has no time for you. If he/she is really busy, add a meeting in his/her calendar. That will show it's important for you and you really need this point. It can be the time to clarify what's good in your work and what needs to be improved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try to find the answer before asking but don't dedicate too much time to it&lt;/strong&gt;. If you're stuck ask for help. You're losing time, even if it seems important to do it on your own and get the glory, you could have done so much more. And when it's solved in two seconds, it’s much better not to wait so much time to ask help ;)&lt;/p&gt;

&lt;h3&gt;
  
  
  To you the middle/senior dev
&lt;/h3&gt;

&lt;p&gt;Some people admire you in secret, I mean really. Take time to help junior dev to grow if you have the capacity to do so. It's also time for you to challenge yourself and get to know your team better as well.&lt;/p&gt;

&lt;p&gt;From my perspective a great middle/senior dev is not just someone who is technically proficient but also  is someone who can help others to grow. An experienced dev should &lt;strong&gt;constantly learn to teach others with more clarity, to better organize their team, and to communicate more effectively&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And you, what do you think?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>team</category>
      <category>productivity</category>
      <category>mentoring</category>
    </item>
    <item>
      <title>Docker services in Github Actions won't have secrets for you</title>
      <dc:creator>Sarah Abd</dc:creator>
      <pubDate>Sun, 17 Nov 2019 15:21:26 +0000</pubDate>
      <link>https://forem.com/sabderemane/how-to-use-docker-services-in-github-actions-6ce</link>
      <guid>https://forem.com/sabderemane/how-to-use-docker-services-in-github-actions-6ce</guid>
      <description>&lt;p&gt;I explain deeper &lt;a href="https://dev.to/s_abderemane/how-to-create-github-actions-to-run-tests-with-services-2653"&gt;how is structured an action and how to use docker services in an article&lt;/a&gt;  but I will focus here more on services. &lt;/p&gt;

&lt;p&gt;Yeah, the great fact is you can use Docker containers as services in Github Actions. 🎉 &lt;/p&gt;

&lt;h2&gt;
  
  
  How do we do it?
&lt;/h2&gt;

&lt;p&gt;Very simple, it is similar to the definition of a service in a &lt;em&gt;docker-compose.yml&lt;/em&gt; but with far fewer parameters.&lt;/p&gt;

&lt;p&gt;We use the keyword &lt;strong&gt;services&lt;/strong&gt; with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the definition of the Docker image to be used&lt;/li&gt;
&lt;li&gt;the list of ports to be exposed of the service&lt;/li&gt;
&lt;li&gt;a list of environment variables&lt;/li&gt;
&lt;li&gt;a list of volumes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not all of these elements are required but good to know.&lt;/p&gt;

&lt;p&gt;In concrete terms, it looks like this, for a Postgres service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="s"&gt;env&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;POSTGRES_BD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;5432/tcp&lt;/span&gt;
  &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example made by Chris Patterson and &lt;a href="https://dev.to/mscccc"&gt;Mike Coutermarsh&lt;/a&gt; for PostgreSQL. You can find the full example with node just &lt;a href="https://github.com/actions/example-services"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We need the Docker image to launch, the port to expose and the name of the service. There is a way to transmit environment values or Docker options as shown in the example above. Sensitive values can be defined with &lt;a href="https://help.github.com/en/github/automating-your-workflow-with-github-actions/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables"&gt;secret key&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full example
&lt;/h2&gt;

&lt;p&gt;For example we want to do an action which launch tests of our Django application on each push event.&lt;/p&gt;

&lt;p&gt;The following workflow is implemented:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;Test Workflow&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;push&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;tests&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;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
    &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;POSTGRES_BD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;5432:5432&lt;/span&gt;
    &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries &lt;/span&gt;&lt;span class="m"&gt;5&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@v1&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;Set up Python 3.5.7&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/setup-python@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;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3.5.7&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;pip install -r requirements.txt&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;Run tests&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;python manage.py test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the job tests consist of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;install Python 3.5.7 on the Ubuntu environment&lt;/li&gt;
&lt;li&gt;install the dependencies&lt;/li&gt;
&lt;li&gt;start the tests with the Postgres database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this example, we still need to override the service values in the Django settings.py for the connection to the PostgreSQL database like that :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;DATABASES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ENGINE&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;django.db.backends.postgresql&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;NAME&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;USER&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;HOST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;localhost&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PORT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have multiple settings for database, you can do with env variable &lt;code&gt;os.environ.get('HOST_NAME')&lt;/code&gt; or a conditional settings with &lt;code&gt;if os.environ.get('GITHUB_WORKFLOW')&lt;/code&gt; for example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Few notes
&lt;/h2&gt;

&lt;p&gt;It is sometimes necessary to require a service status feedback to establish a connection. Therefore, an element is defined that checks the health of the service to know when it is operational (also called a &lt;em&gt;health check&lt;/em&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one is for postgres but you can find multiple such as elasticsearch, mysql and so on...&lt;br&gt;
In case you don’t have a &lt;strong&gt;health check&lt;/strong&gt; available, we pause the process execution with the command sleep, yes it’s not great, I grant you…&lt;/p&gt;

&lt;p&gt;To link the service with the job of the workflow, the &lt;strong&gt;host&lt;/strong&gt; is needed. &lt;br&gt;
In case you're running your workflow :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;in the virtual machine&lt;/em&gt;, it will be &lt;strong&gt;localhost&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;in a container&lt;/em&gt;, it will be &lt;strong&gt;the name of the service&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't forget&lt;/strong&gt;, you can use Docker services only with a Linux distribution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;According to the port, to access it on your job(s), it will be like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;${{ job.services.postgres.ports[5432] }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first example, the machine port 5432 is randomly assigned a free port and accessed.&lt;/p&gt;

&lt;p&gt;Nevertheless, it can be assigned in a fixed way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;5432:5432&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we have the port 5432 of the service related to the port 5432 of the machine defined in the action.&lt;/p&gt;




&lt;p&gt;Here you go, you're ready to use services in your workflow ! 💪&lt;/p&gt;

</description>
      <category>django</category>
      <category>actions</category>
      <category>docker</category>
      <category>workflow</category>
    </item>
    <item>
      <title>How to create Github Actions to run tests with services ?</title>
      <dc:creator>Sarah Abd</dc:creator>
      <pubDate>Tue, 05 Nov 2019 20:05:56 +0000</pubDate>
      <link>https://forem.com/sabderemane/how-to-create-github-actions-to-run-tests-with-services-2653</link>
      <guid>https://forem.com/sabderemane/how-to-create-github-actions-to-run-tests-with-services-2653</guid>
      <description>&lt;p&gt;I’ve been digging GitHub Actions since I received access to the beta. GitHub Actions is generally available since November 11, 2019 and I can explain to you. 🎉&lt;/p&gt;

&lt;p&gt;French version right &lt;a href="https://tkt.paris/comment-creer-une-action-github-pour-tester-son-application-avec-des-services"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y6gTvlL7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AdcmLNHncSQ4306nX" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y6gTvlL7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AdcmLNHncSQ4306nX" alt="" width="800" height="530"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@yancymin?utm_source=medium&amp;amp;utm_medium=referral"&gt;Yancy Min&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is it ?
&lt;/h3&gt;

&lt;p&gt;Github Action is a solution for continuous integration and continuous deployment (CI/CD). It’s a new feature from Github, which is displayed as a tab in your repository. Its operations are triggered by &lt;strong&gt;Git events such as a commit push&lt;/strong&gt;. In order to create a new sequence of events to be run on a commit push, we must create a set of commands which will be carried out according to the specifications of the project. This service is designed to perform processes automatically and continuously for collaborative work on a Git repo once implemented. It should be noted that Github Action is based on Docker, so it’s recommended to have some knowledge about it to use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write your action
&lt;/h3&gt;

&lt;p&gt;An action contains several elements necessary to perform a process: the &lt;strong&gt;on&lt;/strong&gt; event that corresponds to the Github event: push, pull request, etc. During the beta however, only the push and pull request triggers are available.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is of course possible to define the scope of your action, so it does specific tasks on certain branches of your repository but not on others. For example, this may include automatic deployment to a server from the staging branch but not from the dev branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;staging&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we have the &lt;strong&gt;jobs&lt;/strong&gt;. In practice, a job is a series of steps performed in an orderly manner. It has 2 important elements: the environment and the steps to be taken by the service.&lt;br&gt;&lt;br&gt;
The &lt;strong&gt;runs-on&lt;/strong&gt; parameter defines the environment in which the action is performed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are several possible virtual environments for the execution of your action, this can be useful so that it corresponds to the specificities of each one. From Ubuntu 19.10 to Windows 2016, you have the choice 😉&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It should be noted that each job is performed in a new instance of the virtual environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So if you want to perform a series of actions with a link between them, you may want consider doing it in the same job. But it is possible to create job dependencies with the &lt;strong&gt;need&lt;/strong&gt; parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;job1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;job2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;need&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;job1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, job2 will only run when job1 has been completed.&lt;/p&gt;

&lt;p&gt;Then, we have all the steps to perform during the process. With a view to continuous integration, the aim is to launch the tests automatically. However, a number of elements must be defined before the tests can be performed!&lt;/p&gt;

&lt;p&gt;This set is defined by the keyword &lt;strong&gt;steps&lt;/strong&gt;. Each step requires at least one element to be performed, i.e. one of its elements:&lt;/p&gt;

&lt;p&gt;the &lt;strong&gt;uses&lt;/strong&gt; keyword to use a specific element:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a public action&lt;/li&gt;
&lt;li&gt;an action in the same repository&lt;/li&gt;
&lt;li&gt;an action on the Docker Hub or on the Docker public register&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;p&gt;the &lt;strong&gt;run&lt;/strong&gt; keyword to launch a command in bash (knowing that there are several ways to execute a command if necessary)&lt;/p&gt;

&lt;p&gt;Finally, we associate the parameter &lt;strong&gt;name&lt;/strong&gt; to know which step it represents. An example being always more meaningful, so here is a job to test a Django project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;tests&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;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v1&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;Set up Python 3.5.7&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/setup-python@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;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3.5.7&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;pip install -r requirements.txt&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;Run tests&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;python manage.py test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the job tests consist of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;install Python 3.5.7 on the Ubuntu environment&lt;/li&gt;
&lt;li&gt;install the dependencies&lt;/li&gt;
&lt;li&gt;start the tests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For tests in real conditions, a database is needed, hence the &lt;em&gt;implementation of services&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add a service to your action
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;How do we do it?&lt;/em&gt; Very simple, it is similar to the definition of a service in a docker-compose.yml but with far fewer parameters.&lt;/p&gt;

&lt;p&gt;We use the keyword &lt;strong&gt;services&lt;/strong&gt; with :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the definition of the Docker image to be used&lt;/li&gt;
&lt;li&gt;the list of ports to be exposed of the service&lt;/li&gt;
&lt;li&gt;a list of environment variables&lt;/li&gt;
&lt;li&gt;a list of volumes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not all of these elements are required but good to know.&lt;br&gt;&lt;br&gt;
In concrete terms, it looks like this, for a Postgres service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="s"&gt;env&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;POSTGRES_BD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;5432/tcp&lt;/span&gt;
  &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need the Docker image to launch, the port to expose and the name of the service. There is a way to transmit environment values or Docker options as shown in the example above. Sensitive values can be defined with &lt;a href="https://help.github.com/en/github/automating-your-workflow-with-github-actions/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables"&gt;secret key&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In addition, it is sometimes necessary to require a service status feedback to establish a connection. Therefore, an element is defined that checks the health of the service to know when it is operational (also called a health check). I took up the example made by Chris Patterson and &lt;a href="https://dev.to/mscccc"&gt;Mike Coutermarsh&lt;/a&gt; for PostgreSQL.&lt;/p&gt;

&lt;p&gt;In case you don’t have a health check available, we pause the process execution with the command &lt;strong&gt;sleep&lt;/strong&gt; , yes it’s not great, I grant you…&lt;/p&gt;

&lt;p&gt;All this is very good, but we have to make the link between the service and our application. We will do it through the port and for the host it will be &lt;em&gt;localhost&lt;/em&gt; since the service is executed directly in the Ubuntu machine in our example. Otherwise it would have been the name of the service.&lt;/p&gt;

&lt;p&gt;In the previous example, the machine port 5432 is randomly assigned a free port and accessed as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;${{ job.services.postgres.ports[5432] }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nevertheless, it can be assigned in a fixed way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;5432:5432&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we have the port 5432 of the service related to the port 5432 of the machine defined in the action.&lt;/p&gt;

&lt;p&gt;The following workflow is implemented:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;Test Workflow&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;push&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;tests&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;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
    &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;POSTGRES_BD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;5432:5432&lt;/span&gt;
    &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries &lt;/span&gt;&lt;span class="m"&gt;5&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@v1&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;Set up Python 3.5.7&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/setup-python@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;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3.5.7&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;pip install -r requirements.txt&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;Run tests&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;python manage.py test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our example, we still need to override the service values in the Django settings.py for the connection to the PostgreSQL database.&lt;/p&gt;

&lt;p&gt;Then the trick is done, just push some code and hope it works. 😉&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you enjoyed this article, please help out with a&lt;/em&gt; ❤️ &lt;em&gt;or a share. It will help others in the world !&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>django</category>
      <category>actions</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
