<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Site de Sarah Abderemane</title><link href="https://sarahabd.com/fr/" rel="alternate"/><link href="https://sarahabd.com/feeds/rss.xml" rel="self"/><id>https://sarahabd.com/fr/</id><updated>2026-05-06T18:00:00+02:00</updated><entry><title>Le mentorat et moi</title><link href="https://sarahabd.com/fr/blog/me-and-mentorship" rel="alternate"/><published>2026-05-06T18:00:00+02:00</published><updated>2026-05-06T18:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2026-05-06:/fr/blog/me-and-mentorship</id><summary type="html">&lt;p class="first last"&gt;Le mentorat est une excellente façon d'apprendre : quelques-unes de mes réflexions sur le mentorat et la contribution aux projets open source.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour... ça fait un moment, comme d'habitude... 😄&lt;/p&gt;
&lt;p&gt;Aujourd'hui, j'aimerais parler de mentorat. C'est une constante dans ma
vie. J'ai été des deux côtés : mentorée et mentore. Et je peux vous dire
qu'on apprend énormément de cet échange.&lt;/p&gt;
&lt;p&gt;Être mentoré·e, c'est une façon d'apprendre auprès d'une personne experte, ou simplement de personnes qui en savent
plus que soi. Ces personnes qu'on admire sincèrement pour leur travail. Les
mentoré·es ne disent même pas toujours à quel point ils et elles admirent leurs mentors.&lt;/p&gt;
&lt;p&gt;À l'inverse, être mentor est une bonne façon d'apprendre à partager ses
connaissances de la meilleure manière. On voit la personne qu'on accompagne grandir et
prendre ses propres décisions, sans même avoir besoin de nous demander conseil à la
fin, parce qu'on lui a donné les outils pour trouver les réponses
par elle-même. Un jour, peut-être, elle prendra le temps de nous remercier, parce que
sans même s'en rendre compte, on a changé sa vie.&lt;/p&gt;
&lt;p&gt;C'est fou, non ? J'adore le mentorat parce que c'est un échange spécial et
unique : on se sent proche de l'autre, parce qu'en tant que
mentor, on voit une version plus jeune de soi-même chez la personne mentorée, et la
personne mentorée voit en nous ce qu'elle pourrait devenir un jour. Je suis sûre que beaucoup de gens
ne voient pas le mentorat exactement comme moi, mais c'est une expérience extrêmement
enrichissante.&lt;/p&gt;
&lt;p&gt;Le mentorat est une excellente façon d'apprendre, qu'on soit mentoré·e ou
mentor. Oui, les mentors apprennent aussi de l'expérience. Comment
s'assurer que la personne mentorée a compris ce qu'on voulait dire ? Comment
expliquer clairement quelque chose qui nous semble évident à la personne assise
en face ? Les questions de la personne mentorée nous font découvrir des aspects auxquels nous n'avions jamais
pensé. Il y a tellement à apprendre !&lt;/p&gt;
&lt;div class="section" id="mentorat-pour-le-google-summer-of-code"&gt;
&lt;h2&gt;Mentorat pour le Google Summer of Code&lt;/h2&gt;
&lt;p&gt;En parlant de mentorat, je vais de nouveau mettre les mains dans le cambouis et
accompagner quelqu'un pour le Google Summer of Code (GSoC) au sein de l'organisation
Django cette année ! 🥳&lt;/p&gt;
&lt;p&gt;Ce sera la première fois que je serai mentore pour le Google Summer of Code, je suis vraiment
enthousiaste ! J'accompagnerai &lt;a class="reference external" href="https://www.linkedin.com/in/keha-chandrakar-342a1a285/"&gt;Keha
Chandrakar&lt;/a&gt;
avec mon incroyable co-mentor et co-président du groupe de travail Site web,
&lt;a class="reference external" href="https://saptaks.website/"&gt;Saptak Sengupta&lt;/a&gt;✨&lt;/p&gt;
&lt;p&gt;Le projet s'intitule &lt;a class="reference external" href="https://summerofcode.withgoogle.com/programs/2026/projects/zCsh2gn8"&gt;Unified Dark Mode and UI Consistency for Django's Issue
Tracker&lt;/a&gt;
(mode sombre unifié et cohérence de l'interface pour le gestionnaire de tickets de Django),
ce serait un bel ajout pour la communauté.&lt;/p&gt;
&lt;p&gt;Ce projet compte beaucoup pour moi. J'ai déjà contribué à
l'ajout du mode sombre sur le site de Django. C'était ma première contribution
majeure à Django ! Quand on commence à contribuer à un
énorme projet comme Django, c'est à la fois excitant et impressionnant ! J'ai contribué
sans mentor, mais j'ai clairement eu de l'aide en chemin, car la
communauté Django est très accueillante et bienveillante. J'ai beaucoup appris grâce à
cette contribution, et elle est maintenant utilisée par énormément de personnes. Être la
mentore de Keha est une belle façon pour moi de rendre la pareille et d'aider quelqu'un d'autre sur un
sujet que je connais plutôt bien !&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="vous-pourriez-etre-mentor"&gt;
&lt;h2&gt;Vous pourriez être mentor&lt;/h2&gt;
&lt;p&gt;J'ai fait partie de l'organisation &lt;a class="reference external" href="https://djangonaut.space"&gt;Djangonaut Space&lt;/a&gt;,
où nous recrutons des mentors.
Cette organisation et l'organisation Django cherchent toujours des mentors.
Si vous avez déjà contribué à un projet open source lié à
l'écosystème Django, ou si vous en maintenez un, et que vous êtes prêt·e à prendre le
temps d'aider quelqu'un dans son parcours de contribution, pensez au mentorat
comme un moyen d'attirer de nouvelles personnes contributrices sur votre projet. Djangonaut Space
organise plusieurs cohortes, &lt;a class="reference external" href="https://buttondown.com/djangonaut-space"&gt;inscrivez-vous à la newsletter et indiquez votre
intérêt pour le mentorat&lt;/a&gt; :
en tant que navigator (mentor technique) ou captain (mentor communautaire).&lt;/p&gt;
&lt;p&gt;Qui sait, ce sera peut-être votre prochain·e co-mainteneur·se, votre nouveau ou nouvelle coéquipier·ère ou
votre nouvelle personne pour relire votre code ? Il y a des choses qu'on peut tout à fait apprendre
seul·e, et d'autres qu'on n'apprend qu'au contact de quelqu'un d'autre.&lt;/p&gt;
&lt;p&gt;C'est tout pour moi !&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="reflexion"/><category term="django"/></entry><entry><title>Me and Mentorship</title><link href="https://sarahabd.com/blog/me-and-mentorship" rel="alternate"/><published>2026-05-06T18:00:00+02:00</published><updated>2026-05-06T18:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2026-05-06:/blog/me-and-mentorship</id><summary type="html">&lt;p class="first last"&gt;Mentoring is a great way to learn, some of my reflexions on mentoring and contributing to open source projects.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi there.. it’s been a while as usual… 😄&lt;/p&gt;
&lt;p&gt;Today I would like to talk about mentoring. It’s been a constant in my
life. I have been on both sides: mentee and mentor. I can tell you that
you learn so much from this exchange.&lt;/p&gt;
&lt;p&gt;Being a mentee is a way to learn from an expert or just people who know
more than yourself. Those people you truly admire for their work. The
mentees don’t even always tell how much they admire their mentors.&lt;/p&gt;
&lt;p&gt;On the reverse, being a mentor is a good way to learn how to share your
knowledge the best way. You watch the person you’re mentoring grow and
make their own decisions, without ever having to ask you for advice in
the end, because you’ve given them the tools to find the answers on
their own. One day, perhaps, they’ll take the time to thank you, because
without even realizing it, you’ve changed their life.&lt;/p&gt;
&lt;p&gt;It’s crazy, isn’t it? I love mentoring because it’s a special and unique
exchange: you feel close to the other person, because when you’re a
mentor, you see a younger version of yourself in your mentee, and the
mentee sees you as what they might one day become. I’m sure many people
don’t see mentoring exactly the way I do, but it’s an extremely
rewarding experience.&lt;/p&gt;
&lt;p&gt;Mentoring is a great way to learn, whether you’re the mentee or the
mentor. Yes, mentors learn from the experience as well. How can you make
sure your mentee has understood what you meant? How can you clearly
explain something that seems obvious to you to the person sitting across
from you? The mentee’s questions help us discover aspects we had never
considered before. There is so much to learn!&lt;/p&gt;
&lt;div class="section" id="google-summer-of-code-mentorship"&gt;
&lt;h2&gt;Google Summer of Code mentorship&lt;/h2&gt;
&lt;p&gt;Speaking about mentoring, I’m going to get my hands dirty again and
mentor someone for Google Summer of Code (GSoC) for the Django
organization this year! 🥳&lt;/p&gt;
&lt;p&gt;It will be my first time to mentor for Google Summer of Code, I’m really
excited! I will be mentoring &lt;a class="reference external" href="https://www.linkedin.com/in/keha-chandrakar-342a1a285/"&gt;Keha
Chandrakar&lt;/a&gt;
with my amazing co-mentor and co-chair of the Website Working Group
&lt;a class="reference external" href="https://saptaks.website/"&gt;Saptak Sengupta&lt;/a&gt;✨&lt;/p&gt;
&lt;p&gt;The project is &lt;a class="reference external" href="https://summerofcode.withgoogle.com/programs/2026/projects/zCsh2gn8"&gt;Unified Dark Mode and UI Consistency for Django’s Issue
Tracker&lt;/a&gt;,
it would be a nice addition for the community.&lt;/p&gt;
&lt;p&gt;This project means a lot to me. I have previously contributed to the
addition of the dark mode in the Django website. It was my first major
contribution to Django! When you start your contribution journey for a
huge project like Django, it’s exciting and impressive! I did contribute
without any mentor but I definitely had help along the way since the
Django community is so welcoming and helpful. I learned a lot through
this contribution and now it’s used by so many people. Being Keha’s
mentor is a good way for me to give back and help someone else on a
topic I know pretty well!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="you-could-be-the-mentor"&gt;
&lt;h2&gt;You could be the mentor&lt;/h2&gt;
&lt;p&gt;I have been part of the &lt;a class="reference external" href="https://djangonaut.space"&gt;Djangonaut Space&lt;/a&gt;
organization, where we are recruiting people as mentors.
This organization and the Django organization are always looking for mentors.
If you have already contributed to an open source project related to the
Django ecosystem or are maintaining one and you are willing to take the
time to help someone in their contribution journey, consider mentoring
as an option to get new contributors to your project. Djangonaut Space
has multiple cohorts, &lt;a class="reference external" href="https://buttondown.com/djangonaut-space"&gt;sign up to the newsletter and mention your
interest in mentoring&lt;/a&gt;:
being a navigator (technical mentor) or a captain (community mentor).&lt;/p&gt;
&lt;p&gt;Who knows, this might be your new co-maintainer, your new teammate or
your new code reviewer? There are things we can definitely learn on our
own and some things you will only learn from someone else.&lt;/p&gt;
&lt;p&gt;That’s it for me!&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="reflexion"/><category term="django"/></entry><entry><title>2025, le bilan de l'année</title><link href="https://sarahabd.com/fr/blog/2025-year-in-review" rel="alternate"/><published>2026-02-12T10:00:00+01:00</published><updated>2026-02-12T10:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2026-02-12:/fr/blog/2025-year-in-review</id><summary type="html">&lt;p class="first last"&gt;Bonjour, ça fait un moment... Tout d'abord, je vous souhaite une bonne année, meilleurs vœux !!&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour, ça fait un moment, comme d'habitude ! Bonne année, chère lectrice, cher lecteur ! Je vous souhaite le meilleur.&lt;/p&gt;
&lt;p&gt;La fin de mon année 2025 a été vraiment compliquée, donc je suis clairement en retard pour écrire cet article, mais
il n'est jamais trop tard, n'est-ce pas ?&lt;/p&gt;
&lt;p&gt;C'est toujours en écrivant ce genre d'article qu'on réalise tout ce qu'on a accompli,
surtout des choses qu'on ne s'attendait pas à faire, et il y en a eu beaucoup cette année.
Et puis il y a toutes les choses qu'on n'a pas réussi à faire, mais nouvelle année, nouvelles possibilités !&lt;/p&gt;
&lt;p&gt;Alors c'est parti, voici le bilan de l'année de Sarah ! ✨&lt;/p&gt;
&lt;div class="section" id="tl-dr"&gt;
&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;Cette année a été géniale, j'ai réussi à faire des choses que je n'aurais pas imaginé faire, et je suis très reconnaissante pour
tout le soutien que j'ai reçu cette année, pour tous les amis incroyables que j'ai et pour toutes les opportunités que j'ai eues.&lt;/p&gt;
&lt;p&gt;Cette année a aussi été une année d'apprentissage et de croissance pour moi. D'énormes défis personnels m'ont poussée à changer,
à progresser et à avoir plus confiance en moi. Il reste encore beaucoup de travail, mais je sens que je suis sur la bonne voie.&lt;/p&gt;
&lt;p&gt;Mes temps forts de l'année :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Être vice-présidente de la Django Software Foundation (DSF)&lt;/li&gt;
&lt;li&gt;Rencontrer la communauté partout dans le monde&lt;/li&gt;
&lt;li&gt;Organiser une devroom au FOSDEM&lt;/li&gt;
&lt;li&gt;Donner des keynotes dans quelques conférences&lt;/li&gt;
&lt;li&gt;Faire mon premier voyage entièrement en solo&lt;/li&gt;
&lt;li&gt;Voir en vrai des amis que je ne connaissais qu'à distance&lt;/li&gt;
&lt;li&gt;Reprendre le dessin et mes activités créatives&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="benevolat-et-communaute"&gt;
&lt;h2&gt;Bénévolat et communauté&lt;/h2&gt;
&lt;p&gt;J'ai participé et pris la parole à plusieurs conférences cette année, ce qui a été une super expérience pour moi. Je l'ai fait non seulement pour
partager mes connaissances, promouvoir Django et la DSF, mais aussi pour aller à la rencontre de la communauté partout dans le monde.&lt;/p&gt;
&lt;p&gt;En tant que représentante de la DSF, il était important pour moi d'être présente et accessible dans la communauté. C'était aussi une bonne façon
d'échanger avec les gens localement et de recueillir leurs retours sur la façon dont la DSF peut mieux les soutenir et sur ce que nous pourrions améliorer.&lt;/p&gt;
&lt;p&gt;J'ai participé et/ou pris la parole à :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;PyCon IT&lt;/li&gt;
&lt;li&gt;FOSDEM&lt;/li&gt;
&lt;li&gt;DjangoCon Europe&lt;/li&gt;
&lt;li&gt;DjangoCon Africa&lt;/li&gt;
&lt;li&gt;DjangoCongress JP (en ligne)&lt;/li&gt;
&lt;li&gt;PyCon Africa (en ligne)&lt;/li&gt;
&lt;li&gt;PyCon FR&lt;/li&gt;
&lt;li&gt;DjangoDay India&lt;/li&gt;
&lt;li&gt;PyLadiesCon (en ligne)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il y a d'autres conférences auxquelles j'aurais aimé assister sans pouvoir y aller cette année, faute de temps ou de budget,
mais auxquelles j'ai participé d'une certaine façon, comme l'EuroPython, où j'ai aidé à obtenir un stand communautaire.&lt;/p&gt;
&lt;p&gt;J'ai donné ma première keynote à la PyCon IT, ce qui a été une étape énorme pour moi.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Mon badge de keynoteuse pour la PyCon IT avec des stickers : FastAPI, PyCon IT et le poney de Django." src="/images/2025-year-in-review/keynoter-badge-pycon-it.jpg" /&gt;
&lt;p class="caption"&gt;Mon badge de keynoteuse pour la PyCon IT avec quelques stickers&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;C'était effrayant, mais aussi très gratifiant.
Un immense merci à l'équipe d'organisation de m'avoir fait confiance pour cette opportunité !
Ma keynote portait sur la &lt;a class="reference external" href="https://youtu.be/TCNv0MZrxoY"&gt;sensibilisation à l'accessibilité&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Toujours sur l'accessibilité, avec des amis, nous avons organisé la première &lt;a class="reference external" href="https://archive.fosdem.org/2025/schedule/track/inclusive-web/"&gt;Inclusive Web Devroom&lt;/a&gt;.
Le FOSDEM est un énorme événement en Europe et c'était une belle occasion de donner plus de visibilité à ce sujet important.&lt;/p&gt;
&lt;p&gt;Je suis toujours impliquée dans mon espace communautaire préféré, &lt;a class="reference external" href="https://djangonaut.space/"&gt;Djangonaut Space&lt;/a&gt;, où j'ai aidé autant que possible, et je suis passée à un
rôle de conseillère cette année en raison de mes autres engagements.&lt;/p&gt;
&lt;p&gt;Et l'un de ces engagements, c'était d'être vice-présidente de la DSF, ce qui a été un immense honneur pour moi.&lt;/p&gt;
&lt;p&gt;J'ai fait de mon mieux pour représenter la communauté et aider la DSF à accomplir sa mission.
C'est toujours difficile de faire tout ce qu'on avait prévu, surtout en tant que bénévole,
mais je pense que nous avons fait de beaux progrès cette année.&lt;/p&gt;
&lt;p&gt;J'en profite pour remercier toutes les personnes incroyables du conseil d'administration de la DSF
et tous les bénévoles qui font un travail formidable pour soutenir la communauté et le projet.
Je remercie tout particulièrement l'ancien président de la DSF, Thibaud Colas, qui a été un excellent leader et coéquipier 💚&lt;/p&gt;
&lt;p&gt;J'espère pouvoir continuer à grandir, progresser, accueillir des gens dans la communauté Django et
rencontrer d'autres amis du monde entier. Je ferai de mon mieux pour poursuivre l'initiative DSF Member of the Month,
qui est une excellente façon de mettre en lumière les personnes formidables de notre communauté et leurs contributions.&lt;/p&gt;
&lt;p&gt;Je suis sûre qu'il y aura encore plus de choses en 2026 !&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="projets-creatifs-et-personnels"&gt;
&lt;h2&gt;Projets créatifs et personnels&lt;/h2&gt;
&lt;p&gt;Cette année, j'ai réalisé que j'avais complètement abandonné toutes les activités créatives que je faisais avant,
et j'essaie de m'y remettre, car c'est quelque chose que j'aime vraiment et je suis une personne plutôt créative en général.&lt;/p&gt;
&lt;p&gt;J'ai repris le dessin et la peinture, j'adore ça, c'est une bonne façon pour moi de me détendre et de m'exprimer.
J'aimerais aussi essayer d'autres choses créatives comme la photographie, mais je dois d'abord changer d'appareil photo,
alors si vous avez des recommandations, dites-le-moi !&lt;/p&gt;
&lt;p&gt;J'essaie aussi de faire un travail sur moi-même, je pense qu'il est important de prendre soin de soi et de travailler sur son développement personnel.
J'ai lu quelques livres sur ce sujet et ça m'aide vraiment.
Je veux continuer ce travail et progresser dans de nombreux domaines,
je pense qu'il est important d'être une meilleure version de soi-même pour pouvoir aussi aider les autres.&lt;/p&gt;
&lt;p&gt;J'espère partager certains de mes apprentissages et de mes réflexions sur ce sujet à l'avenir, peut-être dans un article ou quelque chose comme ça.&lt;/p&gt;
&lt;p&gt;J'essaie aussi d'apprendre de nouvelles choses, j'ai une longue liste de choses que je veux apprendre, mais je dois les prioriser.&lt;/p&gt;
&lt;p&gt;Parmi les choses que je veux apprendre en 2026 :&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Améliorer mes compétences en dessin&lt;/li&gt;
&lt;li&gt;En apprendre plus sur l'accessibilité web&lt;/li&gt;
&lt;li&gt;En apprendre plus sur le soin de soi et le développement personnel&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="voyages-et-experiences"&gt;
&lt;h2&gt;Voyages et expériences&lt;/h2&gt;
&lt;p&gt;Cette année, j'ai eu la chance de beaucoup voyager, pour des conférences et à titre personnel.
J'adore voyager et découvrir de nouveaux endroits, de nouvelles cultures, et rencontrer de nouvelles personnes.
C'est toujours une belle occasion pour moi de voir aussi des amis en vrai.&lt;/p&gt;
&lt;p&gt;Je suis allée en :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Belgique&lt;/li&gt;
&lt;li&gt;France&lt;/li&gt;
&lt;li&gt;Grèce&lt;/li&gt;
&lt;li&gt;Allemagne&lt;/li&gt;
&lt;li&gt;Irlande&lt;/li&gt;
&lt;li&gt;Italie&lt;/li&gt;
&lt;li&gt;Inde&lt;/li&gt;
&lt;li&gt;Pays-Bas&lt;/li&gt;
&lt;li&gt;Pologne&lt;/li&gt;
&lt;li&gt;Tanzanie&lt;/li&gt;
&lt;li&gt;Royaume-Uni&lt;/li&gt;
&lt;li&gt;États-Unis d'Amérique&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Certains de ces voyages étaient pour des conférences, d'autres pour le travail ou pour des raisons personnelles, mais tous ont été de belles expériences pour moi.
J'ai réalisé que je suis allée sur presque tous les continents cette année, ce que je n'aurais pas imaginé en début d'année.&lt;/p&gt;
&lt;p&gt;J'ai aussi eu la chance de faire mon premier voyage entièrement en solo, une vraie réussite pour moi !&lt;/p&gt;
&lt;p&gt;Je suis d'abord allée à Berlin, en Allemagne, complètement seule, ce qui faisait un peu peur, mais a aussi été très gratifiant.
Chose amusante, j'ai choisi d'y aller pendant un festival des lumières dont je ne connaissais pas l'existence,
j'ai donc eu la chance de voir la ville sous un autre jour, et c'était vraiment magnifique.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="La porte de Brandebourg illuminée en bleu pour le festival des lumières de Berlin" src="/images/2025-year-in-review/festival-of-lights-berlin.jpg" /&gt;
&lt;p class="caption"&gt;La porte de Brandebourg illuminée en bleu pour le festival des lumières de Berlin&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Ensuite, je suis allée en Inde pour le DjangoDay India, qui a aussi été une expérience adorable.
J'ai eu la chance de rencontrer beaucoup de personnes de la communauté et de découvrir le pays.
Je suis restée quelques jours de plus pour visiter d'autres villes, du nord au sud, et c'était vraiment incroyable.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Le palais de Bangalore en Inde" src="/images/2025-year-in-review/bengaluru-palace.jpg" /&gt;
&lt;p class="caption"&gt;Le palais de Bangalore en Inde&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;J'ai vraiment envie de retourner en Inde, il y a tant de choses à voir et à découvrir là-bas.
C'est un pays qu'on adore ou qu'on déteste, mais pour moi,
c'est un endroit plein de charme que j'apprécie vraiment.&lt;/p&gt;
&lt;p&gt;En dehors de l'Asie, je veux faire plus de voyages en Afrique à l'avenir.
J'ai découvert la Tanzanie pour la première fois cette année avec la DjangoCon Africa et c'était incroyable.
J'ai écrit un &lt;a class="reference external" href="/fr/blog/djangocon-africa-2025"&gt;article sur mon expérience à la conférence&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;J'ai vraiment aimé la culture, les gens et la nature là-bas.
Il y a tellement de beaux endroits à voir, et je veux en découvrir davantage.&lt;/p&gt;
&lt;p&gt;L'Europe est aussi un super endroit pour voyager, il y a tellement de belles villes et de beaux pays à découvrir.
Quelques photos de mes voyages en Europe :&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Varsovie en décembre avec les illuminations de Noël" src="/images/2025-year-in-review/warsaw-december-lights.jpg" /&gt;
&lt;p class="caption"&gt;Varsovie en décembre avec les illuminations de Noël, Pologne&lt;/p&gt;
&lt;/div&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="figure"&gt;
&lt;img alt="Une rue du centre de Bologne, en Italie" src="/images/2025-year-in-review/road-in-bologna.jpg" /&gt;
&lt;p class="caption"&gt;Une rue du centre de Bologne, en Italie&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Je suis aussi allée sur le continent américain, mais plutôt au nord pour rendre visite à ma famille, et je veux découvrir davantage le sud à l'avenir.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Le Capitole à Washington DC, aux États-Unis" src="/images/2025-year-in-review/capitol-washington-dc.jpg" /&gt;
&lt;p class="caption"&gt;Le Capitole à Washington DC, aux États-Unis&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;J'ai aussi vécu des choses auxquelles je ne m'attendais pas, comme la fin de ma très longue relation,
qui a été une expérience vraiment difficile, mais je pense que ça a aussi été une bonne occasion pour moi de grandir et d'en apprendre plus sur moi-même.&lt;/p&gt;
&lt;p&gt;Une chose que j'ai apprise de tous ces voyages et de toutes ces expériences, c'est qu'il est important d'être ouvert·e à la nouveauté et de prendre le temps
de prendre soin de soi, surtout quand on est dans un nouvel endroit ou qu'on traverse une période difficile.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="lecons-et-reflexions"&gt;
&lt;h2&gt;Leçons et réflexions&lt;/h2&gt;
&lt;p&gt;J'ai beaucoup appris en 2025, en essayant des choses, en sortant de ma zone de confort et en faisant des erreurs, bien sûr.&lt;/p&gt;
&lt;p&gt;J'ai essayé de me rapprocher de ce que je veux vraiment, ce qui veut dire progresser sur de nombreux sujets.
J'ai amélioré ma prise de parole en public en donnant des talks dans des conférences.
J'ai amélioré mon leadership en étant vice-présidente de la DSF et grâce à d'autres rôles bénévoles.
J'ai encore du travail, mais je suis fière des progrès que j'ai faits.&lt;/p&gt;
&lt;p&gt;Je continue à travailler ma communication, surtout en anglais, et je me sens un peu plus à l'aise maintenant.
J'ai appris à penser davantage à moi et à mes besoins, c'est encore en cours, mais il y a des progrès.&lt;/p&gt;
&lt;p&gt;J'ai aussi beaucoup appris en rencontrant des gens et en discutant avec eux, j'ai eu la chance de rencontrer beaucoup de personnes incroyables cette année,
et j'en suis vraiment reconnaissante.&lt;/p&gt;
&lt;p&gt;Je sais que je suis vraiment douée pour mettre les gens en relation, c'est quelque chose que j'aime beaucoup et que je veux continuer à faire.
J'ai aussi appris qu'il est important de prendre soin de soi et de travailler sur son développement personnel,
je pense qu'il est important d'être une meilleure version de soi-même pour pouvoir aussi aider les autres.&lt;/p&gt;
&lt;p&gt;Ma citation préférée cette année était « Feel the fear and do it anyway » (« Ressens la peur et fais-le quand même ») de Susan Jeffers,
un excellent rappel pour continuer à essayer de nouvelles choses sans avoir peur de l'échec.&lt;/p&gt;
&lt;p&gt;Ma citation pour 2026 est « Try more things, take more risks, embrace more discomfort » (« Essaie plus de choses, prends plus de risques, accepte davantage l'inconfort ») de Peter McKenzie,
un rappel pour continuer à progresser dans de nombreux domaines et accepter de ne pas toujours être à l'aise.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="note-a-moi-meme"&gt;
&lt;h2&gt;Note à moi-même&lt;/h2&gt;
&lt;p&gt;En 2025, j'ai continué à essayer des choses avec lesquelles je n'étais pas à l'aise. Pour 2026, Tim Schilling m'a récemment demandé quel serait mon thème pour cette année,
et je pense que ce serait « lâcher prise et s'aimer soi-même », car je veux continuer à progresser dans de nombreux domaines.&lt;/p&gt;
&lt;p&gt;C'est un long chemin, mais je suis confiante. Ce ne sera pas facile, mais je ne suis pas seule, et ça ne peut que m'aider à devenir une meilleure version
de moi-même et à pouvoir aussi aider les autres.&lt;/p&gt;
&lt;p&gt;Quelques conseils pour cette nouvelle année :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Continuer d'essayer, faire des erreurs, ce n'est pas si grave&lt;/li&gt;
&lt;li&gt;La pratique est importante pour devenir bon·ne dans quelque chose&lt;/li&gt;
&lt;li&gt;Être bienveillant·e envers soi-même&lt;/li&gt;
&lt;li&gt;Lâcher ce qui ne nous sert plus&lt;/li&gt;
&lt;li&gt;Se concentrer sur ce qui compte pour soi&lt;/li&gt;
&lt;li&gt;Célébrer ses progrès, même les plus petits&lt;/li&gt;
&lt;li&gt;Prendre du temps pour prendre soin de soi et réfléchir&lt;/li&gt;
&lt;li&gt;Accueillir le changement et être ouvert·e aux nouvelles opportunités&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Faites ce qui vous rend heureux·se et épanoui·e, et n'ayez pas peur de changer de chemin si celui-ci ne vous convient plus.&lt;/p&gt;
&lt;p&gt;J'espère que cette année sera une belle année pour vous, et je vous souhaite le meilleur pour 2026 !&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="reflexion"/></entry><entry><title>2025, year in review</title><link href="https://sarahabd.com/blog/2025-year-in-review" rel="alternate"/><published>2026-02-12T10:00:00+01:00</published><updated>2026-02-12T10:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2026-02-12:/blog/2025-year-in-review</id><summary type="html">&lt;p class="first last"&gt;Hi there, it has been a while… First of all, I want to say happy new year to you, best wishes !!&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi there, it has been a while as usual! Happy new year dear reader! I hope the best for you.&lt;/p&gt;
&lt;p&gt;My end of the 2025 year has been really tricky for me so I'm definitely late writing this post but it's
never too late for anything right?&lt;/p&gt;
&lt;p&gt;It's always when you write this kind of post that you realized how much you have accomplished,
especially on things you weren't expecting to do, so many things on this field.
And all the things you didn't managed to do but, new year, new possibilities!&lt;/p&gt;
&lt;p&gt;So here we go, Sarah's year in review! ✨&lt;/p&gt;
&lt;div class="section" id="tl-dr"&gt;
&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;This year was awesome, I success to do things and I wouldn't have expected to do, and I am very grateful for
all the support I had this year, all the amazing friends I have, all the opportunities I had.&lt;/p&gt;
&lt;p&gt;This year was also a year of learning and growth for me. Huge personal challenges that has pushed me to change,
improve and be more confident in myself. Still a lot of work to do but I feel I'm on the right path.&lt;/p&gt;
&lt;p&gt;My highlights for the year have been:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Be Vice President of the Django Software Foundation (DSF)&lt;/li&gt;
&lt;li&gt;Meet the community all over the world&lt;/li&gt;
&lt;li&gt;Organized a devroom in FOSDEM&lt;/li&gt;
&lt;li&gt;Keynoting in few conferences&lt;/li&gt;
&lt;li&gt;First full solo travel trip&lt;/li&gt;
&lt;li&gt;See remote friends in real life&lt;/li&gt;
&lt;li&gt;retake drawing and creative skills&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="volunteering-and-community"&gt;
&lt;h2&gt;Volunteering and community&lt;/h2&gt;
&lt;p&gt;I attended and spoke at several conferences this year, which was a great experience for me. I did that not only to
share my knowledge, promote Django and the DSF but also to see the community everywhere in the world.&lt;/p&gt;
&lt;p&gt;As a DSF representative, it was important for me to be present and accessible in the community. It was also a good way
to connect with people locally and get their feedback on how the DSF can better support them and things we could improve.&lt;/p&gt;
&lt;p&gt;I have attended and/or spoken at:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;PyCon IT&lt;/li&gt;
&lt;li&gt;FOSDEM&lt;/li&gt;
&lt;li&gt;DjangoCon Europe&lt;/li&gt;
&lt;li&gt;DjangoCon Africa&lt;/li&gt;
&lt;li&gt;DjangoCongress JP (online)&lt;/li&gt;
&lt;li&gt;PyCon Africa (online)&lt;/li&gt;
&lt;li&gt;PyCon FR&lt;/li&gt;
&lt;li&gt;DjangoDay India&lt;/li&gt;
&lt;li&gt;PyLadiesCon (online)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some others conferences I would have liked to attend but couldn't make it this year due to time or budget constraints
but I was involved in some ways like EuroPython where I helped to get a community booth.&lt;/p&gt;
&lt;p&gt;I gave my first keynote at PyCon IT, which was a huge milestone for me.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="My keynoter badge for PyCon IT with some stickers, FastAPI stickers, PyCon IT stickers and Django pony sticker." src="../images/2025-year-in-review/keynoter-badge-pycon-it.jpg" /&gt;
&lt;p class="caption"&gt;My keynoter badge for PyCon IT with some stickers&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;It was scary but also very rewarding.
Thank you so much the organizing team for trusting me with this opportunity!
My keynote was on &lt;a class="reference external" href="https://youtu.be/TCNv0MZrxoY"&gt;raising awareness on accessibility&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Related to accessibility, with some friends we organized the first &lt;a class="reference external" href="https://archive.fosdem.org/2025/schedule/track/inclusive-web/"&gt;Inclusive Web Devroom&lt;/a&gt;.
FOSDEM is a huge event in Europe and it was a great opportunity to bring more visibility to this important topic.&lt;/p&gt;
&lt;p&gt;Still involved in my favorite community space, &lt;a class="reference external" href="https://djangonaut.space/"&gt;Djangonaut Space&lt;/a&gt;, where I helped as much as I can, and I switched to an
advisor role this year due to my other commitments.&lt;/p&gt;
&lt;p&gt;And one of my commitments was being Vice President of the DSF, which was a huge honor for me.&lt;/p&gt;
&lt;p&gt;I tried my best to represent the community and help the DSF to achieve its mission.
It's always hard to do all the things you have planned, especially as a volunteer,
but I think we made some good progress this year.&lt;/p&gt;
&lt;p&gt;I'm taking this opportunity to thank all the amazing people in the DSF board
and all the volunteers who are doing an amazing job to support the community and the project.
Specially, I want to thank the former DSF president, Thibaud Colas, who has been an excellent leader and teammate 💚&lt;/p&gt;
&lt;p&gt;I hope to be able to continue to grow, improve and welcome people to the Django community and
met other friends from all over the world. I will do my best to continue the DSF Member of the Month initiative,
which is a great way to highlight the great people in our community and their contributions.&lt;/p&gt;
&lt;p&gt;I'm sure there will be more to come in 2026!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="creative-and-personal-projects"&gt;
&lt;h2&gt;Creative and personal projects&lt;/h2&gt;
&lt;p&gt;This year I realized I completely abandoned all the creative work I used to do,
and I'm trying to get back into it because it's something I really enjoy and I'm a fairly creative person in general.&lt;/p&gt;
&lt;p&gt;I retook drawing and painting, I really enjoy it, it's a good way for me to relax and express myself.
I also want to try other creative things like photography, but I need to change my camera first,
so if you have any recommendation, let me know!&lt;/p&gt;
&lt;p&gt;I'm also trying to do some self-work, I think it's important to take care of yourself and work on your personal growth.
I have been reading some books on this topic and it's really helpful for me.
I want to keep doing this work and improve myself in many areas,
I think it's important to be a better version of yourself to be able to help others too.&lt;/p&gt;
&lt;p&gt;I hope to share some of my learnings and insights on this topic in the future, maybe in a blog post or something like that.&lt;/p&gt;
&lt;p&gt;I'm also trying to learn new things, I have a long list of things I want to learn but I need to prioritize them.&lt;/p&gt;
&lt;p&gt;Some of the things I want to learn in 2026 are:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Improve my drawing skills&lt;/li&gt;
&lt;li&gt;Learn more about web accessibility&lt;/li&gt;
&lt;li&gt;Learn more about self-care and personal growth&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="travel-and-experiences"&gt;
&lt;h2&gt;Travel and experiences&lt;/h2&gt;
&lt;p&gt;This year I had the chance to travel a lot for conferences and personal trips.
I love so much to travel and discover new places, cultures, and meet new people.
It's always a great way for me to meet friends in real life too.&lt;/p&gt;
&lt;p&gt;I have been to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Belgium&lt;/li&gt;
&lt;li&gt;France&lt;/li&gt;
&lt;li&gt;Greece&lt;/li&gt;
&lt;li&gt;Germany&lt;/li&gt;
&lt;li&gt;Ireland&lt;/li&gt;
&lt;li&gt;Italy&lt;/li&gt;
&lt;li&gt;India&lt;/li&gt;
&lt;li&gt;Netherlands&lt;/li&gt;
&lt;li&gt;Poland&lt;/li&gt;
&lt;li&gt;Tanzania&lt;/li&gt;
&lt;li&gt;United Kingdom&lt;/li&gt;
&lt;li&gt;United States of America&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some of those trips were for conferences, some were for work or for personal reasons, but all of them were great experiences for me.
I realized I have been to almost all the continents this year, which is something I didn't expect to do when I started the year.&lt;/p&gt;
&lt;p&gt;I also had the chance to do my first full solo travel trip, which was such an achievement for me!&lt;/p&gt;
&lt;p&gt;I went first in Berlin in Germany completely alone, which was a bit scary but also very rewarding.
Funily, I choose to go when there was a festival of lights I didn't know about,
so I had the chance to see the city in a different way and it was really beautiful.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Brandenburg Gate with blue lights for the Festival of lights in Berlin" src="../images/2025-year-in-review/festival-of-lights-berlin.jpg" /&gt;
&lt;p class="caption"&gt;Brandenburg Gate with blue lights for the Festival of lights in Berlin&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Then I went to India for DjangoDay India, which was also a lovely experience.
I had the chance to meet many people from the community and discover the country.
I stayed more days to visit other cities, from the north to the south, and it was really amazing.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Bengaluru palace in India" src="../images/2025-year-in-review/bengaluru-palace.jpg" /&gt;
&lt;p class="caption"&gt;Bengaluru palace in India&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I really want to go back to India, there is so much to see and discover there.
It's a country where you either love it or hate it, but for me,
it's a place that has a lot of charm and I really enjoy it.&lt;/p&gt;
&lt;p&gt;Outside of Asia, I want to do more trips in Africa in the future.
I discover Tanzania for the first time this year with DjangoCon Africa and it was amazing.
I have written a &lt;a class="reference external" href="/blog/djangocon-africa-2025"&gt;blog post about my experience at the conference&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I really enjoyed the culture, the people, and the nature there.
There are so many beautiful places to see and I want to discover more of them.&lt;/p&gt;
&lt;p&gt;Europe is also a great place to travel, there are so many beautiful cities and countries to discover.
Some pictures of my trips in Europe:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Warsaw in December with Christmas lights" src="../images/2025-year-in-review/warsaw-december-lights.jpg" /&gt;
&lt;p class="caption"&gt;Warsaw in December with Christmas lights, Poland&lt;/p&gt;
&lt;/div&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="figure"&gt;
&lt;img alt="Road in the center of Bologna, Italy" src="../images/2025-year-in-review/road-in-bologna.jpg" /&gt;
&lt;p class="caption"&gt;Road in the center of Bologna, Italy&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I have been to Americas too, but more in the north to visit family, I want to discover more of the south in the future.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="The Capitol in Washington DC, USA" src="../images/2025-year-in-review/capitol-washington-dc.jpg" /&gt;
&lt;p class="caption"&gt;The Capitol in Washington DC, USA&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I also experienced some things that I didn't expect to experience, like the breakup of my very long relationship,
which was a really hard experience but I think it was also a good opportunity for me to grow and learn more about myself.&lt;/p&gt;
&lt;p&gt;One thing I learned from all those travels and experiences is that it's important to be open to new things and take time
to take care of yourself, especially when you are in a new place or going through a hard time.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="lessons-and-insights"&gt;
&lt;h2&gt;Lessons and insights&lt;/h2&gt;
&lt;p&gt;I've learned a lot during the 2025's year, by trying things, going out of my comfort zone and making mistakes, of course.&lt;/p&gt;
&lt;p&gt;I tried to be more close to what I really want which means improving myself in many topics.
I improved my public speaking skills by giving talks in conferences.
I improved my leadership skills by being Vice President of the DSF and other volunteering roles.
I still have work to do but I'm proud of the progress I made.&lt;/p&gt;
&lt;p&gt;I keep working on my communication skills, especially in English, and I feel a bit more comfortable now.
I learned to think more about myself and my needs, still a work in progress but there are improvements.&lt;/p&gt;
&lt;p&gt;I also learned a lot by meeting people and chatting with them, I have the chance to meet many amazing people this year
and I'm really grateful for that.&lt;/p&gt;
&lt;p&gt;I know that I'm really good at connecting people to each other, which is something I really enjoy and I want to keep doing it.
I also learned that it's important to take care of yourself and work on your personal growth,
I think it's important to be a better version of yourself to be able to help others too.&lt;/p&gt;
&lt;p&gt;My favorite quote for this year was &amp;quot;Feel the fear and do it anyway&amp;quot; by Susan Jeffers,
which is a great reminder for me to keep trying new things and not be afraid of failure.&lt;/p&gt;
&lt;p&gt;My quote for 2026 is &amp;quot;Try more things, take more risks, embrace more discomfort&amp;quot; by Peter McKenzie,
which is a reminder for me to keep improving myself in many areas and be ok with the fact of not being comfortable.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="reminder-to-myself"&gt;
&lt;h2&gt;Reminder to myself&lt;/h2&gt;
&lt;p&gt;2025 I keep trying things I wasn't comfortable with. 2026, Tim Schilling recently asked me what would be my theme for this year,
I think it would be &amp;quot;letting go and self-love&amp;quot; as I want to keep improving myself in many areas.&lt;/p&gt;
&lt;p&gt;It's a long road but I'm confident. It will not be easy but I'm not alone and it can just help me to be a better version of
myself and be able to help others too.&lt;/p&gt;
&lt;p&gt;Piece of advice to tell for this new year:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Keep trying, making mistakes is not that bad&lt;/li&gt;
&lt;li&gt;Practice is important to be good at something&lt;/li&gt;
&lt;li&gt;Be kind to yourself&lt;/li&gt;
&lt;li&gt;Letting go of what doesn't serve you anymore&lt;/li&gt;
&lt;li&gt;Focus on what matters to you&lt;/li&gt;
&lt;li&gt;Celebrate your progress, no matter how small&lt;/li&gt;
&lt;li&gt;Take time for self-care and reflection&lt;/li&gt;
&lt;li&gt;Embrace change and be open to new opportunities&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Do what makes you happy and fulfilled, and don't be afraid to change your path if it doesn't feel right anymore.&lt;/p&gt;
&lt;p&gt;I hope this year will be a good one for you, and I wish you all the best for 2026!&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="reflexion"/></entry><entry><title>DjangoCon Africa 2025</title><link href="https://sarahabd.com/fr/blog/djangocon-africa-2025" rel="alternate"/><published>2025-08-28T04:00:00+02:00</published><updated>2025-08-28T04:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2025-08-28:/fr/blog/djangocon-africa-2025</id><summary type="html">&lt;p class="first last"&gt;Bonjour, ça fait un moment... Il y a quelques semaines, je suis allée pour la première fois à la DjangoCon Africa. Elle avait lieu à Arusha, en Tanzanie.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour, ça fait un moment, comme d'habitude. Il y a quelques semaines, je suis allée pour la première fois à la DjangoCon Africa. Elle avait lieu à Arusha, en Tanzanie.&lt;/p&gt;
&lt;p&gt;Tim Schilling a écrit un excellent article sur son expérience à la DjangoCon Africa, vous pouvez lire &lt;a class="reference external" href="https://www.better-simple.com/django/2025/08/25/djangocon-africa-2025-recap/"&gt;son article&lt;/a&gt;.
Il y a rassemblé les résumés d'autres participant·es à la conférence.&lt;/p&gt;
&lt;div class="section" id="ma-premiere-djangocon-africa"&gt;
&lt;h2&gt;Ma première DjangoCon Africa&lt;/h2&gt;
&lt;p&gt;C'est toujours un sentiment particulier quand on participe à une conférence pour la première fois.
On rencontre de nouvelles personnes, on découvre comment la conférence est organisée et on se familiarise avec son organisation et son fonctionnement.&lt;/p&gt;
&lt;p&gt;Je connais bien la DjangoCon Europe : j'y ai été organisatrice, bénévole et participante.
Il faut savoir que les événements DjangoCon sont organisés bénévolement.
Je tiens vraiment à remercier les organisateurs, organisatrices et bénévoles derrière cette conférence.
Je sais que ça représente énormément de travail en coulisses, mais rassembler des gens au même endroit et les voir tisser des liens et partager leurs connaissances, c'est une joie inestimable.
Si vous voulez aider la communauté dans son ensemble, c'est une très bonne façon de contribuer.&lt;/p&gt;
&lt;p&gt;Je voudrais aussi remercier tous les sponsors qui ont rendu cette conférence possible.
C'est particulièrement important pour moi, car la communauté doit être représentée dans son ensemble, sur tous les continents, et une conférence comme celle-ci est la meilleure façon de le montrer.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Thibaud Colas et moi devant le mur de la DjangoCon Africa UbuCon Africa avec les logos de tous les sponsors. Nous montrons le nom de la conférence et nous sourions tous les deux." src="/images/me-thibaud-wall.jpg" /&gt;
&lt;p class="caption"&gt;Thibaud et moi devant le mur de la DjangoCon Africa UbuCon Africa&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Je suis fière de cette photo : Thibaud Colas et moi, président et vice-présidente, devant le mur de la DjangoCon Africa UbuCon Africa avec les logos de tous les sponsors.
Le sponsoring est crucial pour la réussite de ce type d'événement, et si la diversité et l'inclusion dans la tech vous tiennent à cœur, soutenir des événements comme la DjangoCon Africa est un excellent moyen de faire la différence.&lt;/p&gt;
&lt;p&gt;En tant que membre du conseil d'administration, je suis contente d'avoir pu participer à presque tous les événements Django organisés dans le monde jusqu'à présent, pour être en contact direct avec la communauté.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="arusha-tanzanie"&gt;
&lt;h2&gt;Arusha, Tanzanie&lt;/h2&gt;
&lt;p&gt;Je n'étais jamais allée dans le sud de l'Afrique, à part dans le pays dont je suis originaire, les &lt;a class="reference external" href="https://fr.wikipedia.org/wiki/Comores_(archipel)"&gt;Comores&lt;/a&gt;.
Aller à la DjangoCon Africa a été une bonne occasion de le découvrir et d'en apprendre plus sur la Tanzanie.
J'ai vraiment aimé Arusha, c'est une ville charmante. C'était un vrai dépaysement pour moi, qui viens de Paris.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Rue avec des boutiques fermées derrière des grilles multicolores à Arusha, en Tanzanie" src="/images/road-with-shops.jpg" /&gt;
&lt;p class="caption"&gt;Rue commerçante à Arusha, en Tanzanie&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;C'est aussi une bonne occasion de découvrir la culture locale, la cuisine et la faune.
J'ai eu le temps de faire un safari dans le cratère du Ngorongoro avec mon adorable ami &lt;a class="reference external" href="https://www.better-simple.com/"&gt;Tim Schilling&lt;/a&gt;, d'aller au marché et de goûter la cuisine locale.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Tim Schilling et moi dans la jeep pendant le safari" src="/images/safari-with-tim.jpg" /&gt;
&lt;p class="caption"&gt;Safari avec Tim Schilling&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;On voit aussi les difficultés auxquelles les gens font face là-bas, et tout ce qu'ils font pour les surmonter. Malgré cela, les gens sont accueillants et chaleureux. Toujours prêts à aider.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="la-conference"&gt;
&lt;h2&gt;La conférence&lt;/h2&gt;
&lt;p&gt;Comme c'était une nouvelle conférence pour moi, j'ai fait de mon mieux pour parler avec le plus de personnes possible.
J'ai été émerveillée par toutes les personnes venues me parler, simplement pour discuter, pour me remercier pour ma keynote ou pour avoir un retour sur leurs projets.
D'habitude, c'est l'inverse : c'est moi qui vais vers les gens. Si vous étiez à la DjangoCon Africa et que nous n'avons pas pu échanger, il n'est pas trop tard !&lt;/p&gt;
&lt;p&gt;Au-delà de la communauté locale, cette conférence m'a donné l'occasion de retrouver de vieux amis et de m'en faire de nouveaux.
Les conférences sont un excellent moyen de voir ses amis à l'international et de rencontrer des gens venus de partout.
Je connais des gens du monde entier, c'est vraiment cool, non ? 😁&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Photo de groupe de toutes les personnes présentes à la DjangoCon Africa 2025" src="/images/group-photo.jpg" /&gt;
&lt;p class="caption"&gt;Tout le monde devant le mur avant la fin de la conférence&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Ce que j'adore, c'est rencontrer en personne des membres de &lt;a class="reference external" href="https://djangonaut.space/"&gt;Djangonaut Space&lt;/a&gt;, en plus de la communauté locale.
J'ai pu rencontrer en personne &lt;a class="reference external" href="https://www.linkedin.com/in/salim-abdella/"&gt;Salim Nuru&lt;/a&gt;, &lt;a class="reference external" href="https://www.philipnarteh.me/"&gt;Philip Nareth&lt;/a&gt; et Tim Schilling.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Cinq membres de Djangonaut Space réunis à la DjangoCon Africa 2025, souriant et pointant le ciel du doigt !" src="/images/djcafrica-djangonauts.jpg" /&gt;
&lt;p class="caption"&gt;L'équipe Djangonaut Space à la DjangoCon Africa 2025&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Je suis triste que &lt;a class="reference external" href="https://rahma.hashnode.dev/"&gt;Rahmat Akintola&lt;/a&gt; n'ait pas pu venir, la prochaine fois j'espère.&lt;/p&gt;
&lt;p&gt;Je peux maintenant dire que j'ai vu en personne tous les fondateurs et cofondateurs de Djangonaut Space 🚀&lt;/p&gt;
&lt;p&gt;Tim est l'un de mes très bons amis, j'étais tellement heureuse de le rencontrer en personne et de pouvoir le soutenir pour sa keynote.
C'est incroyable que ce soit la première fois que nous nous rencontrions en personne, après tout le temps passé ensemble sur Djangonaut Space.
Les relations à distance, c'est bien réel.&lt;/p&gt;
&lt;p&gt;J'étais contente de voir enfin des personnes avec qui j'avais échangé de temps en temps en ligne, comme &lt;a class="reference external" href="https://www.linkedin.com/in/juliusboakye/"&gt;Julius Boakye&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="keynote-d-ouverture"&gt;
&lt;h2&gt;Keynote d'ouverture&lt;/h2&gt;
&lt;p&gt;J'ai été profondément honorée de donner la keynote d'ouverture de la DjangoCon Africa : « 50 shades of green - One contribution to the Django world ».
Pour les personnes intéressées, voici le &lt;a class="reference external" href="https://sarahabd.com/shades"&gt;lien vers les slides&lt;/a&gt;. Je verrai pour ajouter la transcription plus tard.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Moi donnant la keynote d'ouverture à la DjangoCon Africa 2025" src="/images/me-keynoting.jpg" /&gt;
&lt;/div&gt;
&lt;p&gt;Si ma keynote a eu un impact sur vous, même des années plus tard, dites-le-moi, j'aimerais beaucoup entendre votre histoire !&lt;/p&gt;
&lt;p&gt;Malheureusement, les talks n'ont pas été enregistrés lors de cette conférence. J'espère que ce sera le cas la prochaine fois, certains contenus méritent d'être partagés au-delà de l'Afrique.&lt;/p&gt;
&lt;p&gt;Chaque échange a marqué mon parcours, et j'ai hâte de poursuivre ces conversations à l'avenir.
J'ai noué quelques contacts pour de potentielles collaborations et de futurs projets, et j'ai hâte de voir où ces liens et ces projets vont mener.&lt;/p&gt;
&lt;p&gt;Comme je l'ai dit dans ma keynote, j'aimerais encourager les gens à contribuer à Django et à l'open source en général.
Il existe de nombreuses façons de contribuer : le code, la documentation, l'internationalisation ou le soutien à la communauté. Chaque petite contribution compte !
Et même si ça fait peur de commencer à contribuer, rappelez-vous que tout le monde a été débutant·e à un moment donné. Moi y compris.&lt;/p&gt;
&lt;p&gt;Alors n'ayez pas peur de faire le premier pas et de vous impliquer. La communauté Django est un endroit chaleureux et accueillant.&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;Ce voyage a été particulièrement important pour moi. Malgré quelques difficultés personnelles, la chaleur et la générosité de la communauté m'ont aidée à mettre ces soucis de côté.
Mon séjour à la DjangoCon Africa a été vraiment enrichissant, et j'espère pouvoir y retourner en 2027.&lt;/p&gt;
&lt;p&gt;À la prochaine, DjangoCon Africa ! 💚&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="reflexion"/><category term="django"/><category term="conferences"/></entry><entry><title>DjangoCon Africa 2025</title><link href="https://sarahabd.com/blog/djangocon-africa-2025" rel="alternate"/><published>2025-08-28T04:00:00+02:00</published><updated>2025-08-28T04:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2025-08-28:/blog/djangocon-africa-2025</id><summary type="html">&lt;p class="first last"&gt;Hi there, it’s have been a while… I have been for the first time to DjangoCon Africa few weeks ago. It was in Arusha, Tanzania.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi there, it's been a while as usual. I have been for the first time to DjangoCon Africa few weeks ago. It was in Arusha, Tanzania.&lt;/p&gt;
&lt;p&gt;Tim Schilling has written an excellent blog post about his experience at DjangoCon Africa, you can read &lt;a class="reference external" href="https://www.better-simple.com/django/2025/08/25/djangocon-africa-2025-recap/"&gt;his blog post&lt;/a&gt;.
He collected the other abstracts from the conference participants.&lt;/p&gt;
&lt;div class="section" id="first-djangocon-africa"&gt;
&lt;h2&gt;First DjangoCon Africa&lt;/h2&gt;
&lt;p&gt;It's always a special feeling when it's your first time in a conference.
You meet new people, discover how the conference is run and familiarize yourself with the organization and how it is supposed to work.&lt;/p&gt;
&lt;p&gt;I know DjangoCon Europe well, I have been an organizer, a volunteer and an attendee.
One thing you have to know is DjangoCon events are run by volunteers for free.
I really would like to thank the organizers and volunteers behind this conference.
I know it's a lot of work behind the scenes, but gathering people in one place and seeing folks connecting and share knowledge it's a priceless joy.
If you want to help the community globally, this is a really good way to contribute.&lt;/p&gt;
&lt;p&gt;Moreover, I would like to thank all the sponsors that made this conference possible.
This is particularly important to me because the community must be represented as a whole across all continents and conference like this one is the best way to show that.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Thibaud Colas and I in front the wall of DjangoCon Africa UbuCon Africa with all sponsors logos. We are showing the name of the conference and both smiling." src="../images/me-thibaud-wall.jpg" /&gt;
&lt;p class="caption"&gt;Thibaud and I showing the DjangoCon Africa UbuCon Africa wall&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I am proud of this picture, Me and Thibaud Colas, Vice President and President, in front the wall of DjangoCon Africa UbuCon Africa with all sponsors logos.
Sponsoring is crucial for the success of such events and if you care about diversity and inclusion in tech, supporting events like DjangoCon Africa is a great way to make a difference.&lt;/p&gt;
&lt;p&gt;As a board member, I am glad to have been able to participate in almost all Django events organized around the world so far to be in direct contact with the community.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="arusha-tanzania"&gt;
&lt;h2&gt;Arusha, Tanzania&lt;/h2&gt;
&lt;p&gt;I have never been to South of Africa except the country I have roots, &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Comoro_Islands"&gt;Comoros Islands&lt;/a&gt;.
Go to DjangoCon Africa was a good way to discover that and learn about Tanzania.
I really enjoyed Arusha, it's a lovely city. It was a real change of landscape for me, coming from Paris.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Road with closed shops in multi-colored jails in Arusha, Tanzania" src="../images/road-with-shops.jpg" /&gt;
&lt;p class="caption"&gt;Road with shops in Arusha, Tanzania&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;It's also a good opportunity to discover the local culture, food and wildlife.
I had the time to do a Safari to Ngorongoro Crater with my lovely friend &lt;a class="reference external" href="https://www.better-simple.com/"&gt;Tim Schilling&lt;/a&gt;, go to the markets and try the local food.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Tim Shilling and I in the Jeep during the safari" src="../images/safari-with-tim.jpg" /&gt;
&lt;p class="caption"&gt;Safari with Tim Schilling&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Also, you see the challenge people are facing there and doing their best to overcome them. Despite this, people are welcoming and friendly. Always trying to help.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-conference"&gt;
&lt;h2&gt;The conference&lt;/h2&gt;
&lt;p&gt;Since it's a new conference for me, I tried my best to talk with as many folks as possible.
I was amazed by all the folks that came to me to talk, just for chatting or thanks me for my keynote and/or get feedback for their projects.
Usually it's the reverse, I will go to folks to talk to them. If you were at DjangoCon Africa and didn't connect with me, you can still do it!&lt;/p&gt;
&lt;p&gt;Outside of the local community, this conference gave me the opportunity to met old friends and new friends.
Conferences are a great way to see your international friends and meet new folks from everywhere.
I know folks from all over the world, that's really cool no? 😁&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Group photo of everyone in DjangoCon Africa 2025" src="../images/group-photo.jpg" /&gt;
&lt;p class="caption"&gt;Everyone in front the wall before the end of the conference&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Something I love is to meet folks from &lt;a class="reference external" href="https://djangonaut.space/"&gt;Djangonaut Space&lt;/a&gt; in person in addition to the local community.
I was able to meet &lt;a class="reference external" href="https://www.linkedin.com/in/salim-abdella/"&gt;Salim Nuru&lt;/a&gt;, &lt;a class="reference external" href="https://www.philipnarteh.me/"&gt;Philip Nareth&lt;/a&gt; and Tim Schilling in person.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Five members of Djangonaut Space meeting up at DjangoCon Africa 2025, smiling and pointing to the sky!" src="../images/djcafrica-djangonauts.jpg" /&gt;
&lt;p class="caption"&gt;The Djangonaut Space crew at DjangoCon Africa 2025&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I'm sad &lt;a class="reference external" href="https://rahma.hashnode.dev/"&gt;Rahmat Akintola&lt;/a&gt; wasn't able to come, next time hopefully.&lt;/p&gt;
&lt;p&gt;Now I can say I have seen all the founders and co-founders of Djangonaut Space in person 🚀&lt;/p&gt;
&lt;p&gt;Tim is one of my very good friends, I was so happy to meet him in person and be able to support him for his keynote.
It's unbelievable that was the first time we met in person, after all the time we spent together on Djangonaut Space.
Remote relationships are real.&lt;/p&gt;
&lt;p&gt;I was glad to finally see folks who I have chatted with online occasionally like &lt;a class="reference external" href="https://www.linkedin.com/in/juliusboakye/"&gt;Julius Boakye&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="opening-keynote"&gt;
&lt;h2&gt;Opening Keynote&lt;/h2&gt;
&lt;p&gt;I was deeply honored to give the opening keynote of DjangoCon Africa: &amp;quot;50 shades of green - One contribution to the Django world&amp;quot;.
For those who are interested, you have the &lt;a class="reference external" href="https://sarahabd.com/shades"&gt;link of the slides&lt;/a&gt; . I will see to add the transcript later.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Me giving the opening keynote at DjangoCon Africa 2025" src="../images/me-keynoting.jpg" /&gt;
&lt;/div&gt;
&lt;p&gt;If my keynote has any impact on you, even years later, please tell me, I would like to hear your story!&lt;/p&gt;
&lt;p&gt;Unfortunately, talks were not recorded at this conference. I hope it will be the case next time, some content deserves to be shared beyond Africa.&lt;/p&gt;
&lt;p&gt;Each interaction has left a mark on my journey, and I look forward to continuing these conversations in the future.
I got some contacts for potential collaborations and projects, and I'm excited to see where these connections and projects will lead.&lt;/p&gt;
&lt;p&gt;As I mentioned in my keynote, I would like to encourage folks to contribute to Django and open source in general.
There are many ways to contribute, whether it's through code, documentation, internationalization or community support. Every little bit helps!
And even if it feels scary to start contributing, remember that everyone was a beginner at some point. Myself included.&lt;/p&gt;
&lt;p&gt;So don't be afraid to take that first step and get involved. The Django community is a friendly and welcoming place.&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;This trip was especially meaningful for me. Despite navigating some personal challenges, the warmth and generosity of the community helped me set those worries aside.
My time at DjangoCon Africa was truly enriching, and I look forward to the possibility of returning in 2027.&lt;/p&gt;
&lt;p&gt;See you next time DjangoCon Africa! 💚&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="reflexion"/><category term="django"/><category term="conferences"/></entry><entry><title>Vice-présidente de la DSF en 2025</title><link href="https://sarahabd.com/fr/blog/dsf-vice-president-2025" rel="alternate"/><published>2025-02-20T12:00:00+01:00</published><updated>2025-02-20T12:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2025-02-20:/fr/blog/dsf-vice-president-2025</id><summary type="html">&lt;p class="first last"&gt;Bonjour, ça fait un moment depuis mon dernier article, mais je reviens avec un nouveau rôle...&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour, ça fait un moment, comme toujours 🙂
J'ai vécu une fin d'année 2024 et un début 2025 difficiles (un deuil familial), donc je n'ai malheureusement pas fait mon bilan de l'année habituel, mais j'ai pris le temps d'écrire ma dernière actualité : je suis la nouvelle vice-présidente de la Django Software Foundation 🎉&lt;/p&gt;
&lt;p&gt;C'est un tel honneur de siéger au conseil d'administration de la Django Software Foundation, et encore plus en tant que vice-présidente. Je suis particulièrement contente d'avoir ce rôle, car c'est une façon d'être en lien avec nos membres, et j'ai déjà reçu de très gentilles réponses par e-mail en accueillant de nouveaux membres de la DSF.&lt;/p&gt;
&lt;div class="section" id="les-missions-de-la-vice-presidente"&gt;
&lt;h2&gt;Les missions de la vice-présidente&lt;/h2&gt;
&lt;p&gt;La vice-présidence gère tout ce qui concerne les demandes d'adhésion à la DSF. Actuellement, vous pouvez candidater pour vous-même ou pour quelqu'un d'autre. Ensuite, la demande est examinée puis soumise au vote du conseil d'administration, qui l'approuve ou non.&lt;/p&gt;
&lt;p&gt;Si vous prévoyez de proposer quelqu'un comme membre de la DSF, ajoutez autant d'informations que possible : ça nous aide vraiment à savoir si la personne remplit les critères pour être approuvée.&lt;/p&gt;
&lt;p&gt;Mes missions sont :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;envoyer des e-mails aux membres approuvés&lt;/li&gt;
&lt;li&gt;les ajouter à la liste de diffusion utilisée pour les votes des futurs conseils d'administration et du steering council&lt;/li&gt;
&lt;li&gt;les ajouter à la section privée des membres de la DSF sur le forum&lt;/li&gt;
&lt;li&gt;leur attribuer le rôle DSF&lt;/li&gt;
&lt;li&gt;assurer le suivi de toute demande spécifique concernant les membres actuels ou en cours d'intégration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En plus de ça, je suis aussi la suppléante du président. Si Thibaud est malade ou ne peut pas faire quelque chose lié à son rôle, c'est moi qui prendrai le relais. Pas de pression, n'est-ce pas ? 😛&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://thib.me/president-of-the-django-software-foundation"&gt;Comme Thibaud l'expliquait sur son blog&lt;/a&gt;, il y a des choses à découvrir pour pouvoir remplir le rôle comme les gens et nous-mêmes l'attendons. Je suis sûre que nous allons trouver et le documenter 💪🏽
La présidence semble être un rôle avec énormément de choses à faire, et je ferai de mon mieux pour l'aider autant que possible.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="mes-projets-pour-2025-et-l-avenir"&gt;
&lt;h2&gt;Mes projets pour 2025 et l'avenir&lt;/h2&gt;
&lt;p&gt;J'ai fait beaucoup de bénévolat l'année dernière. Une chose difficile, c'est de trouver le bon équilibre pour pouvoir faire tout ce qu'on veut tout en prenant du temps pour soi. Selon sa personnalité, il peut être encore plus difficile de dire non à un sujet qui nous tient à cœur simplement parce qu'on n'a pas assez de temps. C'est pourquoi mon premier objectif est d'améliorer les processus et de documenter les choses en interne pour la vice-présidence, au cas où je déciderais de ne pas continuer à siéger au conseil.&lt;/p&gt;
&lt;p&gt;Cette année, j'aimerais automatiser partiellement ou complètement le processus d'intégration d'un nouveau membre de la DSF, afin de réduire le délai entre l'annonce de l'approbation des membres et le moment où ils sont réellement intégrés et ajoutés. Ça permettra aussi à la vice-présidence de consacrer du temps à d'autres choses.&lt;/p&gt;
&lt;p&gt;Je continuerai mon travail sur ce que j'ai mentionné dans ma déclaration de candidature et je ferai de mon mieux pour représenter la Django Software Foundation, ce super framework et les personnes qui le font vivre partout dans le monde 💚&lt;/p&gt;
&lt;p&gt;Je vais essayer de concrétiser les choses sur lesquelles je n'ai pas mené autant d'actions que je le voulais (accessibilité, site web de Django, etc.) et soutenir les autres membres du conseil ainsi que toutes les personnes prêtes à s'impliquer dans la gouvernance de Django et dans le travail autour de Django qui contribue à la mission de la DSF.&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="django"/><category term="dsf"/><category term="reflexion"/></entry><entry><title>DSF Vice President 2025</title><link href="https://sarahabd.com/blog/dsf-vice-president-2025" rel="alternate"/><published>2025-02-20T12:00:00+01:00</published><updated>2025-02-20T12:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2025-02-20:/blog/dsf-vice-president-2025</id><summary type="html">&lt;p class="first last"&gt;Hi there, it has been a while since my last post, but I'm now back with a new role...&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi there, it's been a while, as always 🙂
I had a though end of the 2024 year and beginning of 2025 (family loss) so I didn't do my usual year in review unfortunately, but I took the time to write my recent update: I'm the new Vice President of the Django Software Foundation 🎉&lt;/p&gt;
&lt;p&gt;This is such an honor to serve on the board of the Django Software Foundation, and it's even more the case as the Vice President. I'm particularly glad to have this role since it's a way to connect to our members and I already had lovely emails responses while onboarding new DSF members.&lt;/p&gt;
&lt;div class="section" id="vice-president-tasks"&gt;
&lt;h2&gt;Vice President tasks&lt;/h2&gt;
&lt;p&gt;The Vice President handle everything related to requests of new DSF members. Currently you can apply for yourself or apply for someone else. After that, it's reviewed and voted by the board for approval or not.&lt;/p&gt;
&lt;p&gt;If you planning to submit a DSF member, please add as many informations as you can, it's really helping us to know if the person meet the criterias to approuve the member.&lt;/p&gt;
&lt;p&gt;My tasks are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;send emails to approved members&lt;/li&gt;
&lt;li&gt;add them to the mailing list used for the voting for the future boards and steering council&lt;/li&gt;
&lt;li&gt;add them to the private DSF member section in the forum&lt;/li&gt;
&lt;li&gt;attribute them the DSF role&lt;/li&gt;
&lt;li&gt;follow up for any specific inquiries related to current or onboarding members&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Besides that, I'm also the fallback of the President. If Thibaud is sick or can't do something related to his role, I will be the one to fill up the place. No fear, right? 😛&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://thib.me/president-of-the-django-software-foundation"&gt;As Thibaud was saying in his blog&lt;/a&gt;, there is some discovery to do to be able to fill the role as people and ourselves expected. I'm sure we will figure it out and document it 💪🏽
The President seems to be a role with many things to do and I will do my best to help him as much as I can.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="my-plans-for-2025-and-the-future"&gt;
&lt;h2&gt;My plans for 2025 and the future&lt;/h2&gt;
&lt;p&gt;I have been doing a lot of volunteering last year, one thing which is hard, is get a good balance to be able to do everything you wanted and take time for yourself. In function of your personality, it can be even harder to say no to a topic you care about just because you don't have enough time. That's why, my first plan is to improve processes and document things internally for the Vice President in case I decide to not continue to serve the board.&lt;/p&gt;
&lt;p&gt;This year I would like to automate partially or completely the process of onboarding a new DSF member to have less time gap in terms of announcement of members approval and the time they are actually onboarded and added. This will be also a way to allow the Vice President to spend time on other things too.&lt;/p&gt;
&lt;p&gt;I will continue my work related what I mentioned in my statement and will do my best to represent the Django Software Foundation and this nice framework and people behind it around the world 💚&lt;/p&gt;
&lt;p&gt;I will see to achieve things I haven't done as many actions as I wanted (Accessibility, Django website etc.) and support other board members and any folks who are happy to step in, in the Django governance and Django work that fulfill the DSF's mission.&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="django"/><category term="dsf"/><category term="reflexion"/></entry><entry><title>TIL : les Protocol et le typage en Python</title><link href="https://sarahabd.com/fr/til/python-protocol-typing" rel="alternate"/><published>2024-12-18T14:00:00+01:00</published><updated>2024-12-18T14:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2024-12-18:/fr/til/python-protocol-typing</id><summary type="html">&lt;p class="first last"&gt;Les Protocol en Python, expliqués simplement par moi&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour,&lt;/p&gt;
&lt;p&gt;J'apprends encore beaucoup de choses sur Python, et j'ai découvert les Protocol il y a
quelques mois. Je voulais l'écrire pour ne pas oublier.&lt;/p&gt;
&lt;p&gt;Les Protocol ont été introduits dans Python 3.8 avec la &lt;a class="reference external" href="https://www.notion.so/TIL-python-Protocol-and-typing-67e79fcf2547409cafb77a5594380008?pvs=21"&gt;PEP
544&lt;/a&gt;.
Il existe plusieurs protocoles en Python, mais celui dont je parle est une
façon de définir du typage structurel. Certaines personnes appellent aussi ça
une interface implicite. On peut utiliser la classe &lt;tt class="docutils literal"&gt;Protocol&lt;/tt&gt; du
module &lt;tt class="docutils literal"&gt;typing&lt;/tt&gt;. Pour ne pas vous embrouiller davantage, je vais l'expliquer
avec une image simple.&lt;/p&gt;
&lt;p&gt;Imaginons que vous êtes journaliste et que vous écrivez des articles tech,
des notes de la semaine et plein d'autres types de textes ; il y a toujours des choses que vous ferez
pour vos publications, quel que soit leur type, par exemple :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;les marquer comme brouillon&lt;/li&gt;
&lt;li&gt;les publier&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour être sûr·e de ne pas les oublier, créons un modèle.
Ce modèle sera votre protocole.&lt;/p&gt;
&lt;p&gt;Avec du vrai code, ça ressemblerait à ceci :&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;typing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Protocol&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Publishable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Protocol&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;   &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Et voilà, vous pouvez l'utiliser pour n'importe quel type de publication &lt;strong&gt;sans
héritage&lt;/strong&gt;. Cela signifie qu'un objet est conforme à un protocole s'il
implémente les méthodes requises. Voici un exemple avec la méthode
publish :&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;   &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="c1"&gt;# do something to publish&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;La classe &lt;tt class="docutils literal"&gt;Article&lt;/tt&gt; implémente maintenant le protocole &lt;tt class="docutils literal"&gt;Publishable&lt;/tt&gt; grâce à l'ajout de la méthode requise &lt;tt class="docutils literal"&gt;publish&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Les avantages et inconvénients sont les suivants :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Avantages&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Pas besoin d'héritage, moins de liens directs, et on évite les inconvénients
de l'héritage quand on fait des changements&lt;/li&gt;
&lt;li&gt;On n'oublie pas d'implémenter des choses et on gagne en dynamisme&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Inconvénients&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Moins lisible, il faut le savoir&lt;/li&gt;
&lt;li&gt;Utile surtout pour le typage&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je suppose que vous vous dites : super, mais comment j'utilise ce Protocol ?
Bonne question !&lt;/p&gt;
&lt;p&gt;Les Protocol sont principalement utilisés pour les annotations de type et la vérification statique des types.
Cela signifie que vous pouvez utiliser un protocole comme annotation de type pour indiquer qu'un
argument ou une variable doit être conforme à un protocole donné.&lt;/p&gt;
&lt;p&gt;Si on reprend notre exemple, on obtient le code suivant :&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;publish_article&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Ici, un seul Protocol est utilisé, mais vous pourriez en utiliser
plusieurs.&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Draft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Protocol&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;   &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;mark_as_draft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="c1"&gt;# do something to mark as draft&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="k"&gt;pass&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;DraftAndPublishable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Draft&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Publishable&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Dans cet exemple, on définit un protocole nommé &lt;tt class="docutils literal"&gt;Draft&lt;/tt&gt; avec
une méthode &lt;tt class="docutils literal"&gt;mark_as_draft&lt;/tt&gt;. Puis on définit un autre protocole
nommé &lt;tt class="docutils literal"&gt;DraftAndPublishable&lt;/tt&gt; qui combine les protocoles
&lt;tt class="docutils literal"&gt;Draft&lt;/tt&gt; et &lt;tt class="docutils literal"&gt;Publishable&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Si vous connaissez les méthodes spéciales &lt;tt class="docutils literal"&gt;__iter__&lt;/tt&gt; et
&lt;tt class="docutils literal"&gt;__next__&lt;/tt&gt; : si vous implémentez les deux, votre objet utilisera le
protocole Iterator ✨ Vous pouvez en apprendre plus dans &lt;a class="reference external" href="https://realpython.com/python-iterators-iterables/#what-is-the-python-iterator-protocol"&gt;l'article de Real Python
sur le protocole
Iterator&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pour conclure, les Protocol permettent de définir du typage structurel en
Python, et donc de créer des interfaces sans avoir besoin d'héritage
explicite. Ils permettent aux vérificateurs de types de s'assurer que les objets respectent
les protocoles définis, ce qui améliore la justesse et la maintenabilité du code.&lt;/p&gt;
&lt;p&gt;C'est tout pour le moment ! J'espère que ça sera utile à quelqu'un.&lt;/p&gt;
</content><category term="til"/><category term="python"/><category term="til"/></entry><entry><title>TIL: python Protocol and typing</title><link href="https://sarahabd.com/til/python-protocol-typing" rel="alternate"/><published>2024-12-18T14:00:00+01:00</published><updated>2024-12-18T14:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2024-12-18:/til/python-protocol-typing</id><summary type="html">&lt;p class="first last"&gt;Python Protocols, the simple explanation from me&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi there,&lt;/p&gt;
&lt;p&gt;I’m still learning a lot around Python, and I discovered Protocol some
months ago and I wanted to write that down to not forget.&lt;/p&gt;
&lt;p&gt;Protocol was created in Python 3.8 with the &lt;a class="reference external" href="https://www.notion.so/TIL-python-Protocol-and-typing-67e79fcf2547409cafb77a5594380008?pvs=21"&gt;PEP
544&lt;/a&gt;.
There a multiple protocols in python but the one I’m talking about is a
way to define structural typing. Some of you will also call that
implicit interface. We can use the &lt;tt class="docutils literal"&gt;Protocol&lt;/tt&gt; class from
the &lt;tt class="docutils literal"&gt;typing&lt;/tt&gt; module. To not confuse you even more, I will explain that
with a simple image.&lt;/p&gt;
&lt;p&gt;If we consider you as a journalist and you are writing tech articles,
week notes and many type of writing; you always have things you will do
for your posts despite the type of them, for example, such as:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;mark it as draft&lt;/li&gt;
&lt;li&gt;publish&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To make sure you not forget those things, let’s create a template, so
you don’t forget them. This template will be your protocol.&lt;/p&gt;
&lt;p&gt;With real code it should look like something like this:&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;typing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Protocol&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Publishable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Protocol&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;   &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;That’s it, you can use it on any types of posts you want &lt;strong&gt;without
inheritating them&lt;/strong&gt;. This means that an object conforms to a protocol by
implementing the required methods. Here’s an example with the publish
method:&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;   &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="c1"&gt;# do something to publish&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;The class &lt;tt class="docutils literal"&gt;Article&lt;/tt&gt; is now implementing the protocol &lt;tt class="docutils literal"&gt;Publishable&lt;/tt&gt; with the addition of the required method &lt;tt class="docutils literal"&gt;publish&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The pro and cons of that are:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pro&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;No need of inheritance pattern, less direct links and avoid drawbacks
of inheritance if you make changes&lt;/li&gt;
&lt;li&gt;Don’t forget to implement things and have more dynamics&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Less readable, you have to know that&lt;/li&gt;
&lt;li&gt;Useful mostly for typing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I guess right now you’re thinking, great but how do I use this Protocol?
Good question!&lt;/p&gt;
&lt;p&gt;Protocols are primarily used for type hinting and static type checking.
This means you can use a protocol as a type annotation to indicate that
an argument or variable must conform to a specific protocol.&lt;/p&gt;
&lt;p&gt;If we retake our example, we will have this following code:&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;publish_article&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;In this case it’s only one Protocol used, but you could have multiple
Protocols used.&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Draft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Protocol&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;   &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;mark_as_draft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="c1"&gt;# do something to mark as draft&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="k"&gt;pass&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;DraftAndPublishable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Draft&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Publishable&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;In this example, we define a protocol named &lt;tt class="docutils literal"&gt;Draft&lt;/tt&gt; with
a &lt;tt class="docutils literal"&gt;mark_as_draft&lt;/tt&gt; method. Then we define another protocol
named &lt;tt class="docutils literal"&gt;DraftAndPublishable&lt;/tt&gt; that combines both
the &lt;tt class="docutils literal"&gt;Draft&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;Publishable&lt;/tt&gt; protocols.&lt;/p&gt;
&lt;p&gt;If you are familiar with the special methods &lt;tt class="docutils literal"&gt;__iter__&lt;/tt&gt; and
&lt;tt class="docutils literal"&gt;__next__&lt;/tt&gt;, if you implement both, then your object will use the
Iterator protocol ✨ You can learn more on &lt;a class="reference external" href="https://realpython.com/python-iterators-iterables/#what-is-the-python-iterator-protocol"&gt;Real Python blog post
related to Iterator
Protocol&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To conclude with, Protocols provide a way to define structural typing in
Python, allowing you to create interfaces without the need for explicit
inheritance. They enable type checkers to verify that objects adhere to
the defined protocols, enhancing code correctness and maintainability.&lt;/p&gt;
&lt;p&gt;That’s it for now! I hope it will be useful for someone.&lt;/p&gt;
</content><category term="til"/><category term="python"/><category term="til"/></entry><entry><title>Conseil d'administration de la DSF : AMA après 8 mois</title><link href="https://sarahabd.com/fr/blog/dsf-board-ama-after-8-months" rel="alternate"/><published>2024-11-16T06:00:00+01:00</published><updated>2024-11-16T06:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2024-11-16:/fr/blog/dsf-board-ama-after-8-months</id><summary type="html">&lt;p class="first last"&gt;Mon expérience et toutes les questions qu'on m'a posées sur le conseil d'administration de la DSF&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour, ça fait un moment. J'ai toujours plein d'idées d'articles et jamais le temps,
mais j'essaie d'en trouver pour parler du conseil d'administration de la &lt;a class="reference external" href="https://www.djangoproject.com/foundation/"&gt;Django Software Foundation&lt;/a&gt; (DSF).
J'oublierai peut-être certaines choses, donc je ferai peut-être une série d'articles sur la DSF.
Cette fois, j'ai décidé de réécrire cet article et de répondre directement aux questions qu'on m'a posées sur les réseaux sociaux ou en personne.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AVERTISSEMENT&lt;/strong&gt; : il s'agit de mon avis personnel, je n'ai l'intention de blâmer personne, à part moi-même.
Ce sont mes réflexions sur ces derniers mois, sachant que j'apprends encore comment fonctionne le conseil.&lt;/p&gt;
&lt;div class="section" id="comment-es-tu-devenue-membre-du-conseil-d-administration-de-la-dsf"&gt;
&lt;h2&gt;Comment es-tu devenue membre du conseil d'administration de la DSF ?&lt;/h2&gt;
&lt;p&gt;J'ai été élue par les &lt;a class="reference external" href="https://www.djangoproject.com/foundation/individual-members/"&gt;membres de la DSF&lt;/a&gt;. Si vous voulez en savoir plus sur l'adhésion à la DSF,
vous pouvez consulter le site de Django, et si vous pensez que vous ou quelqu'un d'autre pourriez convenir, candidatez.
J'ai commencé à siéger au conseil en janvier 2024, et mon mandat se terminera en décembre 2025.
Chaque membre du conseil a un mandat de 2 ans, et il existe 4 rôles spécifiques :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Président·e&lt;/li&gt;
&lt;li&gt;Vice-président·e&lt;/li&gt;
&lt;li&gt;Trésorier·ère&lt;/li&gt;
&lt;li&gt;Secrétaire&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je n'ai pas de rôle spécifique, je voulais d'abord voir comment ça se passait, puis voir ce que je pouvais faire.
Et aussi comment ça allait se combiner avec mes tâches actuelles et mon (énorme) liste de choses à faire.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="qu-est-ce-qui-est-different-de-ce-que-tu-imaginais"&gt;
&lt;h2&gt;Qu'est-ce qui est différent de ce que tu imaginais ?&lt;/h2&gt;
&lt;p&gt;Je pense qu'en venant de l'organisation de &lt;a class="reference external" href="https://djangonaut.space/"&gt;Djangonaut Space&lt;/a&gt;, je m'attendais à des similitudes en termes de communication
et d'organisation, mais ce n'était pas le cas. Je m'attendais à plus de communication et d'interactions asynchrones, puisque
nous pouvons tous être occupés pour de nombreuses raisons.&lt;/p&gt;
&lt;p&gt;Des choses un peu plus définies, comme qui doit répondre aux e-mails et que faire des spams, par exemple.&lt;/p&gt;
&lt;p&gt;1 h de réunion du conseil par mois, ce n'est pas suffisant pour moi, et certains sujets ne sont pas vraiment discutés en dehors des réunions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="que-faudrait-il-faire-a-l-avenir-pour-assurer-le-succes-a-long-terme-du-conseil-et-de-la-dsf"&gt;
&lt;h2&gt;Que faudrait-il faire à l'avenir pour assurer le succès à long terme du conseil et de la DSF ?&lt;/h2&gt;
&lt;p&gt;Faire plus d'efforts sur la levée de fonds : je crois qu'avoir plus d'argent permettra d'agir dans plus de domaines.&lt;/p&gt;
&lt;p&gt;Et aussi, avoir un meilleur lien avec la communauté.
Parfois, nous rencontrons des problèmes pour lesquels les retours et le soutien de la communauté seraient utiles pour les résoudre.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="parmi-tes-initiatives-au-conseil-combien-pourraient-etre-menees-sans-etre-membre-du-conseil"&gt;
&lt;h2&gt;Parmi tes initiatives au conseil, combien pourraient être menées SANS être membre du conseil ?&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Par exemple, le problème de l'intégration et de l'accompagnement des nouvelles personnes contributrices est traité par Djangonaut Space,
de notre propre initiative. Mais approuver des subventions et sélectionner une équipe pour la DjangoCon Europe ne peut être fait que par des membres du conseil.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;En fait, énormément de choses peuvent être faites sans être membre du conseil 😁&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Aider les gens sur le &lt;a class="reference external" href="https://forum.djangoproject.com/"&gt;forum Django&lt;/a&gt; ou le &lt;a class="reference external" href="https://discord.gg/xcRH6mN4fa"&gt;Discord Django&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Modérer le forum et le Discord&lt;/li&gt;
&lt;li&gt;Lancer un &lt;a class="reference external" href="https://github.com/django/dsf-working-groups"&gt;groupe de travail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Participer à un groupe de travail&lt;/li&gt;
&lt;li&gt;Aider sur le contenu du site de Django&lt;/li&gt;
&lt;li&gt;Proposer des personnes comme membres de la DSF&lt;/li&gt;
&lt;li&gt;Créer une communauté Django locale (par exemple le meetup Django Paris)&lt;/li&gt;
&lt;li&gt;Chercher des communautés partout dans le monde pour les ajouter à &lt;a class="reference external" href="https://www.djangoproject.com/community/local/"&gt;la page des communautés locales&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Contribuer aux sites djangoproject.com / code.djangoproject.com&lt;/li&gt;
&lt;li&gt;Contribuer au &lt;a class="reference external" href="https://github.com/django-discord/bot"&gt;bot Discord de Django&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Contribuer au cœur de Django pour améliorer les processus&lt;/li&gt;
&lt;li&gt;Contribuer à une &lt;a class="reference external" href="https://www.djangoproject.com/foundation/teams/"&gt;équipe Django&lt;/a&gt; (par exemple l'équipe de tri et de revue)&lt;/li&gt;
&lt;li&gt;Parler à des personnes qui pourraient rejoindre un groupe de travail&lt;/li&gt;
&lt;li&gt;Être bénévole pour la présence de Django/de la DSF lors d'événements (par exemple aider à tenir un stand Django)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="de-petites-facons-de-s-impliquer-si-je-n-ai-que-5-heures-par-mois-pour-contribuer-ou-avez-vous-besoin-de-monde"&gt;
&lt;h2&gt;De petites façons de s'impliquer : si je n'ai que 5 heures par mois pour contribuer, où avez-vous besoin de monde ?&lt;/h2&gt;
&lt;p&gt;Il existe de nombreuses façons de contribuer, selon ce qui vous intéresse le plus :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Actions immédiates&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Aider le groupe de travail Réseaux sociaux à fournir ou relire du contenu&lt;/li&gt;
&lt;li&gt;Aider les Djangonautes sur le forum ou sur Discord, répondre aux questions&lt;/li&gt;
&lt;li&gt;Retweeter/partager sur Mastodon les publications de Django&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Peut nécessiter une validation / actions futures&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Aider à la modération (par exemple Reddit /r/django)&lt;/li&gt;
&lt;li&gt;Le groupe de travail Levée de fonds de la DSF pourrait avoir besoin d'aide pour contacter des sponsors potentiels&lt;/li&gt;
&lt;li&gt;Si possible, venir aux &lt;a class="reference external" href="https://www.djangoproject.com/weblog/2024/oct/16/announcing-weekly-dsf-office-hours/"&gt;permanences de la DSF&lt;/a&gt; pour aider à répondre ou contribuer à la conversation&lt;/li&gt;
&lt;li&gt;J'aimerais à terme avoir une équipe dédiée au contenu du site, et de l'aide serait la bienvenue ici&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si l'une de ces actions vous intéresse, remplissez &lt;a class="reference external" href="https://framaforms.org/help-sarah-in-her-dsf-mission-1731706938"&gt;ce formulaire&lt;/a&gt;,
pour que je puisse vous contacter plus tard en cas de besoin précis.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="la-dsf-fixe-t-elle-et-suit-elle-des-objectifs-de-diversite-et-d-inclusion-et-si-oui-comment"&gt;
&lt;h2&gt;La DSF fixe-t-elle et suit-elle des objectifs de diversité et d'inclusion, et si oui comment ?&lt;/h2&gt;
&lt;p&gt;Nous avons une &lt;a class="reference external" href="https://www.djangoproject.com/diversity/"&gt;déclaration publique sur la diversité&lt;/a&gt; et quelques améliorations en cours en matière de DEI.&lt;/p&gt;
&lt;p&gt;Actuellement, il s'agit surtout de définir l'état des lieux et son évolution avec des statistiques, pour pouvoir fixer des objectifs.&lt;/p&gt;
&lt;p&gt;Les actions menées visent surtout à montrer la diversité de la communauté dans le monde de Django, c'est-à-dire :
le site, les élections, les membres et les outils de communication de Django :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;La page des communautés locales&lt;/li&gt;
&lt;li&gt;Reconnaître des membres de la DSF du monde entier&lt;/li&gt;
&lt;li&gt;De petites initiatives pour aider à obtenir une bonne représentation de la diversité de la communauté lors des élections du conseil de la DSF&lt;/li&gt;
&lt;li&gt;Parler des membres actuels de la DSF&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On pourrait aller plus loin, par exemple en faisant participer Django au &lt;a class="reference external" href="https://www.outreachy.org/"&gt;programme Outreachy&lt;/a&gt;, etc.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="quelles-sont-les-taches-et-le-temps-a-y-consacrer"&gt;
&lt;h2&gt;Quelles sont les tâches et le temps à y consacrer ?&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Les tâches régulières comme base, puis les tâches ponctuelles/initiatives personnelles, avec une estimation du temps&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Nous avons une réunion chaque mois, qui dure une heure. Pendant ce temps, nous passons en revue tous les sujets en cours et nouveaux
avec tous les membres et l'assistante, Catherine.&lt;/p&gt;
&lt;p&gt;En dehors de ça, nous communiquons de manière asynchrone sur Slack.&lt;/p&gt;
&lt;p&gt;Comme je n'ai pas de rôle spécifique, il s'agit surtout de promouvoir et de représenter la Django Software Foundation, et de
suivre des groupes de travail de la DSF en tant que référente du conseil. Nous avons un formulaire de contact, donc je dois vérifier les e-mails et y répondre si
je peux.&lt;/p&gt;
&lt;p&gt;Pour les tâches ponctuelles/initiatives personnelles, je ne connais pas précisément le temps, mais je pense que ça dépend de la tâche :
s'il s'agit de recherches sur un sujet ou de faire quelque chose pour un groupe de travail. Je suis impliquée dans 3 groupes de travail,
ce qui veut dire qu'il peut y avoir des réunions ou des actions à faire en lien avec eux.&lt;/p&gt;
&lt;p&gt;C'est difficile de définir un temps précis, mais je pense pouvoir dire environ 5 heures ou plus par mois, selon les besoins et
ma santé.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="dans-quels-domaines-le-conseil-pourrait-il-s-ameliorer-et-ou-manque-t-il-de-competences-d-expertise"&gt;
&lt;h2&gt;Dans quels domaines le conseil pourrait-il s'améliorer, et où manque-t-il de compétences/d'expertise ?&lt;/h2&gt;
&lt;p&gt;Je pense que le conseil pourrait s'améliorer en matière de promotion : trouver des sponsors, proposer des offres de sponsoring selon le niveau
de sponsoring, obtenir des contacts...&lt;/p&gt;
&lt;p&gt;Et je crois que nous manquons d'expertise sur les questions juridiques et le marketing.
Par exemple, Django est connu des développeurs et développeuses pour sa stabilité et ses mises à jour sans douleur, c'est quelque chose
qui n'est pas mis en avant, ou alors mal, en disant qu'il est « ennuyeux ».&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="des-choses-en-coulisses-des-points-douloureux"&gt;
&lt;h2&gt;Des choses « en coulisses » ? Des points douloureux ?&lt;/h2&gt;
&lt;p&gt;Je devrais vraiment partager ce qui se passe en coulisses ? 😁&lt;/p&gt;
&lt;p&gt;Je pense que le principal point douloureux pour moi, ça a été la communication et la documentation.&lt;/p&gt;
&lt;p&gt;Beaucoup de choses ne sont pas documentées, ou seulement en partie, et avec tous les conseils successifs, j'imagine que des choses se sont perdues avec le temps.
C'est difficile de tout comprendre quand on est nouvelle.&lt;/p&gt;
&lt;p&gt;J'aurais aussi préféré que les tâches soient partagées, ou éventuellement que les gens puissent/soient encouragés à demander de l'aide s'ils n'ont pas le temps
ou pour toute autre raison, surtout quand ils ont un rôle qui peut être très prenant.
J'ai mis beaucoup de temps à comprendre qui rédige nos pages d'actualités.
Les accès et les processus pour les demander ne sont pas toujours clairs pour moi.
Ce genre de choses devrait être documenté quelque part.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="comment-le-conseil-prend-il-ses-decisions-votez-vous-sur-tout"&gt;
&lt;h2&gt;Comment le conseil prend-il ses décisions (votez-vous sur tout) ?&lt;/h2&gt;
&lt;p&gt;Comme je le disais, nous avons une réunion du conseil chaque mois, avec un ordre du jour précis que nous passons en revue
ensemble :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Demandes de subventions&lt;/li&gt;
&lt;li&gt;Propositions de DjangoCon&lt;/li&gt;
&lt;li&gt;Adhésions à la DSF&lt;/li&gt;
&lt;li&gt;Groupes de travail de la DSF&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tous ces sujets sont soumis au vote à chaque fois qu'il y a quelque chose à voter,
donc nous nous assurons d'avoir le quorum avant le début de la réunion, sinon elle est reportée.
Nous discutons aussi de sujets liés à l'organisation de la DSF, comme les statuts, la marque, etc.,
mais tout n'est pas soumis au vote, sauf en cas de changement majeur.
Tous les membres du conseil peuvent ajouter un sujet à l'ordre du jour.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="pour-quelles-choses-faut-il-impliquer-le-conseil-et-que-peut-on-simplement-faire"&gt;
&lt;h2&gt;Pour quelles choses faut-il impliquer le conseil, et que peut-on « simplement faire » ?&lt;/h2&gt;
&lt;p&gt;Certains &lt;a class="reference external" href="https://github.com/django/dsf-working-groups"&gt;groupes de travail de la DSF&lt;/a&gt; existent déjà : tous leurs membres sont identifiables, ainsi que la façon de les rejoindre.&lt;/p&gt;
&lt;p&gt;Tout le monde peut aider un groupe de travail sans demander à un membre du conseil.&lt;/p&gt;
&lt;p&gt;Tout le monde peut créer un groupe de travail de la DSF, mais il faut au moins un membre du conseil pour suivre et guider le
groupe de travail (= référent·e du conseil) selon la vision du conseil de la DSF et pour faire le lien. Quand la proposition est prête,
la ou le référent·e la présente en réunion pour qu'elle soit votée par le conseil.&lt;/p&gt;
&lt;p&gt;Il existe aussi des initiatives comme Djangonaut Space, &lt;a class="reference external" href="https://django-news.com/"&gt;Django News&lt;/a&gt;, etc., qui ne dépendent pas du tout du conseil.
Si vous avez une idée qui pourrait résoudre un problème dans la communauté Django, lancez-vous !&lt;/p&gt;
&lt;p&gt;La principale chose qui implique le conseil, c'est la création d'une nouvelle DjangoCon, puisque le nom est déposé sous
la marque Django avec certains critères. Vous pouvez tout de même créer des événements plus petits sans le conseil,
et certains sont recensés sur &lt;a class="reference external" href="https://www.djangoproject.com/community/local/"&gt;la page des communautés locales&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="tes-reflexions-personnelles-est-ce-un-plaisir-ou-une-corvee"&gt;
&lt;h2&gt;Tes réflexions personnelles : est-ce un plaisir ou une corvée ?&lt;/h2&gt;
&lt;p&gt;Difficile à dire, j'ai connu les deux.&lt;/p&gt;
&lt;p&gt;J'ai été frustrée de ne pas pouvoir aider dans certains cas, ou de voir des gens se plaindre sans que l'information remonte
directement au niveau du conseil, là où elle aurait pu faire la différence. Alors je prends des notes et j'essaie de faire changer les choses, mais parfois
c'est juste une question de temps ou d'actions, ça ne se passe pas comme on voulait et on est déçu·e du résultat.&lt;/p&gt;
&lt;p&gt;J'apprécie aussi quand des gens me remercient pour certaines actions, quand je les vois émerveillés par la reconnaissance de leur adhésion à la DSF,
ou simplement quand je vois des personnes que je connais d'autres espaces (Djangonaut Space, Discord...) participer à la communauté Django
d'une manière ou d'une autre, même si ça ne se termine pas comme prévu, comme lors des élections. C'est vraiment beau de voir des gens du monde
entier se rassembler autour d'une chose en commun.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="ou-en-es-tu-de-tes-objectifs-sommes-nous-sur-la-bonne-voie-sinon-de-quelles-ressources-faudrait-il-pour-les-atteindre"&gt;
&lt;h2&gt;Où en es-tu de tes objectifs ? Sommes-nous sur la bonne voie ? Sinon, de quelles ressources faudrait-il pour les atteindre ?&lt;/h2&gt;
&lt;p&gt;Si on reprend &lt;a class="reference external" href="https://www.djangoproject.com/weblog/2023/nov/13/2024-dsf-board-candidates/"&gt;ma déclaration de candidature publiée sur le blog de Django&lt;/a&gt;,
voici où on en est :&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;span class="underline"&gt;Augmenter la levée de fonds&lt;/span&gt; : &lt;strong&gt;en cours&lt;/strong&gt; avec le groupe de travail Levée de fonds de la DSF
        &lt;ul&gt;
            &lt;li&gt;&lt;span class="underline"&gt;améliorer la communication&lt;/span&gt; : des idées ont été partagées avec le groupe de travail Réseaux sociaux de la DSF, il manque la coordination avec le groupe de travail Levée de fonds quand l'équipe aura tout ce qu'il faut&lt;/li&gt;
            &lt;li&gt;&lt;span class="underline"&gt;mettre en valeur les sponsors&lt;/span&gt; : ce sera revu avec le futur groupe de travail Site web de la DSF, en coordination avec le groupe de travail Levée de fonds&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;span class="underline"&gt;Développer notre communauté&lt;/span&gt; : &lt;strong&gt;en cours&lt;/strong&gt;, avec beaucoup de nouveaux membres de la DSF et de nouvelles personnes
        &lt;ul&gt;
            &lt;li&gt;&lt;span class="underline"&gt;aider en particulier les contributeurs et contributrices, actuels et nouveaux&lt;/span&gt; : faire connaître la communauté et rencontrer des gens lors d'autres événements.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;span class="underline"&gt;Groupe de travail sur le mentorat&lt;/span&gt; : &lt;strong&gt;discussion lancée&lt;/strong&gt;. Je suis impliquée dans trop de groupes de travail, mais j'ai maintenant une bénévole pour mener ce projet ✨ Elle aura besoin de personnes et de ressources pour l'aider, une issue sera bientôt ouverte, gardez un œil dessus.&lt;/li&gt;
    &lt;li&gt;&lt;span class="underline"&gt;Faire progresser l'accessibilité dans le framework&lt;/span&gt; : &lt;strong&gt;en cours&lt;/strong&gt;, nous avons de nouveaux membres et beaucoup d'idées et de discussions en cours. Cela dépend aussi beaucoup du groupe de travail Site web de la DSF, qui sera bientôt lancé.&lt;/li&gt;
    &lt;li&gt;&lt;span class="underline"&gt;La diversité de Django et l'élargissement de la communauté&lt;/span&gt; : &lt;strong&gt;en cours&lt;/strong&gt;, avoir une meilleure représentation dans Django, par exemple parmi les candidat·es aux élections ou les personnes mises en avant sur le site.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Je pense que nous sommes sur la bonne voie, mais je ne peux pas le faire seule, surtout pour les réseaux sociaux : nous aurons besoin de personnes pour nous aider à promouvoir et à écrire du contenu.&lt;/p&gt;
&lt;p&gt;Il y a aussi des sujets sur lesquels j'aimerais que plus de personnes s'impliquent :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Le groupe de travail Code de conduite de la DSF&lt;/li&gt;
&lt;li&gt;La modération du Discord et du forum&lt;/li&gt;
&lt;li&gt;Une future équipe pour rédiger le contenu du site&lt;/li&gt;
&lt;li&gt;Recueillir les retours des gens pour apporter des améliorations&lt;/li&gt;
&lt;li&gt;Recueillir les retours des sponsors&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="qu-as-tu-accompli"&gt;
&lt;h2&gt;Qu'as-tu accompli ?&lt;/h2&gt;
&lt;p&gt;Je suis contente de ce que j'ai accompli, même si je pensais en faire plus.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Représenter la DSF à certains événements (par exemple le FOSDEM)&lt;/li&gt;
&lt;li&gt;Le stand Django à l'EuroPython&lt;/li&gt;
&lt;li&gt;Un lightning talk à la DjangoCon Europe&lt;/li&gt;
&lt;li&gt;Le panel de la DSF à la DjangoCon Europe&lt;/li&gt;
&lt;li&gt;Gérer les rôles DSF sur le serveur Discord&lt;/li&gt;
&lt;li&gt;Répondre à des questions sur Discord, le forum ou par e-mail&lt;/li&gt;
&lt;li&gt;Aider à lancer le groupe de travail Levée de fonds de la DSF&lt;/li&gt;
&lt;li&gt;Ajouter des communautés locales sur la page des communautés locales&lt;/li&gt;
&lt;li&gt;Suivre le brouillon du groupe de travail Site web de la DSF&lt;/li&gt;
&lt;li&gt;Aider à la revue des propositions de DjangoCon pour l'année prochaine&lt;/li&gt;
&lt;li&gt;Aider le groupe de travail Réseaux sociaux&lt;/li&gt;
&lt;li&gt;Faire des recherches sur les anciens conseils et l'histoire de la DSF&lt;/li&gt;
&lt;li&gt;Aider sur le prochain sondage des développeurs et développeuses Django&lt;/li&gt;
&lt;li&gt;Proposer beaucoup de personnes comme membres de la DSF&lt;/li&gt;
&lt;li&gt;Lister les demandes potentielles des Djangonautes&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="qu-aimerais-tu-accomplir"&gt;
&lt;h2&gt;Qu'aimerais-tu accomplir ?&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Automatiser partiellement ou complètement l'ajout de nouveaux membres individuels de la DSF&lt;/li&gt;
&lt;li&gt;Améliorer la levée de fonds pour pouvoir mener plus d'actions&lt;/li&gt;
&lt;li&gt;Améliorer le site avec le groupe de travail Site web de la DSF&lt;/li&gt;
&lt;li&gt;Créer une équipe (un groupe de travail ?) dédiée au contenu du site&lt;/li&gt;
&lt;li&gt;Créer un groupe de travail sur le mentorat/le leadership&lt;/li&gt;
&lt;li&gt;Créer un moyen de recueillir les retours de la communauté&lt;/li&gt;
&lt;li&gt;Améliorer les formulaires pour les futures élections&lt;/li&gt;
&lt;li&gt;Créer une série d'articles sur les membres de la DSF&lt;/li&gt;
&lt;li&gt;Créer des publications « le saviez-vous ? » sur la DSF pour les réseaux sociaux&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="qu-aimerais-tu-que-la-communaute-sache-pour-te-faciliter-la-tache"&gt;
&lt;h2&gt;Qu'aimerais-tu que la communauté sache pour te faciliter la tâche ?&lt;/h2&gt;
&lt;p&gt;Ça demande en fait du temps si on veut faire des choses en dehors de la réunion mensuelle.
Le travail et les activités à côté prennent du temps, et certains jours, c'est difficile de travailler sur l'open source.&lt;/p&gt;
&lt;p&gt;Nous devons augmenter les financements, et la meilleure façon de commencer, c'est vous, chère lectrice, cher lecteur.
Si vous travaillez pour une entreprise, demandez-lui si elle sponsorise Django si elle l'utilise, et expliquez-lui pourquoi elle devrait le faire.
Si vous ne savez pas quoi dire, vous pouvez commencer par le fait que ça aide à payer nos Fellows,
les 2 femmes incroyables qui maintiennent chaque jour l'outil dont elle dépend, en assurant sa sécurité et ses améliorations.&lt;/p&gt;
&lt;p&gt;Beaucoup de choses pourraient être résolues avec de l'argent, mais pas seulement. Parfois, ce qui nous manque, ce sont des personnes.
Des mentors, des personnes pour répondre aux questions, des personnes pour modérer les plateformes, des personnes pour contribuer au code source.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="qu-est-ce-qui-t-a-fait-rire"&gt;
&lt;h2&gt;Qu'est-ce qui t'a fait rire ?&lt;/h2&gt;
&lt;p&gt;Mon intégration, ce n'était vraiment pas ce que j'imaginais, même si, pour être honnête, je n'attendais pas grand-chose.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="le-referais-tu"&gt;
&lt;h2&gt;Le referais-tu ?&lt;/h2&gt;
&lt;p&gt;Je pense que oui, pas parce que c'est particulièrement amusant, mais plutôt parce que certaines choses ne peuvent changer qu'à un certain niveau,
et je pense que je peux être utile ici.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="si-tu-as-le-syndrome-de-l-imposteur-comment-le-geres-tu"&gt;
&lt;h2&gt;Si tu as le syndrome de l'imposteur, comment le gères-tu ?&lt;/h2&gt;
&lt;p&gt;Le syndrome de l'imposteur est malheureusement mon meilleur ami, toujours là, je ne sais pas pourquoi, lol&lt;/p&gt;
&lt;p&gt;Je pense que c'est une question de réfléchir à la meilleure façon de faire : même si je ne suis pas la personne la plus compétente,
je pense que j'ai quelque chose à apporter, et c'est pour ça que j'ai été élue.&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="dsf"/><category term="django"/></entry><entry><title>DSF Board, AMA after 8 months</title><link href="https://sarahabd.com/blog/dsf-board-ama-after-8-months" rel="alternate"/><published>2024-11-16T06:00:00+01:00</published><updated>2024-11-16T06:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2024-11-16:/blog/dsf-board-ama-after-8-months</id><summary type="html">&lt;p class="first last"&gt;My experience and all the questions folks have asked me about DSF Board&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi there, it's been a while, I always have many ideas to write and no time,
but I try to find some to talk about the &lt;a class="reference external" href="https://www.djangoproject.com/foundation/"&gt;Django Software Foundation&lt;/a&gt; (DSF) board.
I might forget things to say so I might do a DSF blog series.
This time I decided to re-write this post and directly answer questions I was asked on social media or in person.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DISCLAIMER&lt;/strong&gt;: This is my personal opinion, I do not intend to blame anyone except myself.
This is my reflection from the past few months, including the fact I’m still learning about the board.&lt;/p&gt;
&lt;div class="section" id="how-did-you-become-a-dsf-board-member"&gt;
&lt;h2&gt;How did you become a DSF board member?&lt;/h2&gt;
&lt;p&gt;I was elected by &lt;a class="reference external" href="https://www.djangoproject.com/foundation/individual-members/"&gt;DSF members&lt;/a&gt;. If you want to learn more about DSF membership,
you can check the django website and if you think you or someone else are suitable, please apply.
I started to serve on the board from January 2024, and my term will end in December 2025.
Each board member have 2 term year and we have 4 specific officer roles:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;President&lt;/li&gt;
&lt;li&gt;Vice President&lt;/li&gt;
&lt;li&gt;Treasurer&lt;/li&gt;
&lt;li&gt;Secretary&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I don’t have any specific role, I was planning to see how it’s going and then see what I can do.
And also, how it will go with my current tasks and (huge) to-do list.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="whats-different-from-your-expectations"&gt;
&lt;h2&gt;What’s different from your expectations?&lt;/h2&gt;
&lt;p&gt;I think coming back from &lt;a class="reference external" href="https://djangonaut.space/"&gt;Djangonaut Space&lt;/a&gt; organization I was expecting some similarities in terms of communication
and organisation but it wasn't the case. I was expecting more asynchronous communication and interaction since
we might all be busy for many reasons.&lt;/p&gt;
&lt;p&gt;A bit more defined things like who should answer emails and what about spams for example.&lt;/p&gt;
&lt;p&gt;1h of board meetings a month is not enough to me and some topics are not really discussed outside the meetings.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-do-you-think-needs-to-happen-in-the-future-to-set-the-board-and-the-dsf-up-for-long-term-success"&gt;
&lt;h2&gt;What do you think needs to happen in the future to set the board and the DSF up for long term success?&lt;/h2&gt;
&lt;p&gt;Put more effort in fundraising, I believe having more money will help to take actions in more domains.&lt;/p&gt;
&lt;p&gt;Also, have a better link with the community.
Sometimes we have issues where having feedback and support from the community would be helpful to address them.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="how-many-of-your-dsf-board-specific-initiatives-are-things-that-could-be-done-not-being-a-board-member"&gt;
&lt;h2&gt;How many of your DSF board specific initiatives are things that could be done NOT being a board member?&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;For example, solving the problem of onboarding and nurturing new contributors is tackled by Djangonaut Space
on our own initiative. But approving grants and selecting a DjangoCon Europe team can only be done by board members.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So many things can be done without being a board member actually 😁&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Help people in the &lt;a class="reference external" href="https://forum.djangoproject.com/"&gt;Django forum&lt;/a&gt; or &lt;a class="reference external" href="https://discord.gg/xcRH6mN4fa"&gt;Django discord&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Moderate the forum and discord&lt;/li&gt;
&lt;li&gt;Initiate a &lt;a class="reference external" href="https://github.com/django/dsf-working-groups"&gt;working group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Participate to a working group&lt;/li&gt;
&lt;li&gt;Help with the content of the Django’s website&lt;/li&gt;
&lt;li&gt;Submit people as DSF members&lt;/li&gt;
&lt;li&gt;Create a local Django community (ie: Django Paris meetup)&lt;/li&gt;
&lt;li&gt;Search for community around the world to add to &lt;a class="reference external" href="https://www.djangoproject.com/community/local/"&gt;the local community page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Contribute to djangoproject.com / code.djangoproject.com website&lt;/li&gt;
&lt;li&gt;Contribute to the &lt;a class="reference external" href="https://github.com/django-discord/bot"&gt;Django Discord bot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Contribute to Django core to improve processes&lt;/li&gt;
&lt;li&gt;Contribute to a &lt;a class="reference external" href="https://www.djangoproject.com/foundation/teams/"&gt;Django team&lt;/a&gt; (ie: Triage and review team)&lt;/li&gt;
&lt;li&gt;Talk to people who could be part of a working group&lt;/li&gt;
&lt;li&gt;Volunteer in Django/DSF presence in events (ie: help run a Django booth)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="small-ways-to-get-involved-if-i-only-have-5-hours-per-month-i-can-contribute-where-do-you-need-people"&gt;
&lt;h2&gt;Small ways to get involved: If I only have 5 hours per month I can contribute, where do you need people?&lt;/h2&gt;
&lt;p&gt;They are many ways to contribute depends on the things you are more interested:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Immediate actions&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Help social media WG to provide content or review content&lt;/li&gt;
&lt;li&gt;Help Djangonauts on the forum or on discord, answer questions&lt;/li&gt;
&lt;li&gt;Retweet/retooth Django posts&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Might need review / futures actions&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Help on moderation (for example Reddit /r/django)&lt;/li&gt;
&lt;li&gt;DSF Fundraising WG might need extra help to reach potential sponsors&lt;/li&gt;
&lt;li&gt;If possible, come on the &lt;a class="reference external" href="https://www.djangoproject.com/weblog/2024/oct/16/announcing-weekly-dsf-office-hours/"&gt;DSF office hours&lt;/a&gt; to help answers or contribute to the conversation&lt;/li&gt;
&lt;li&gt;I would like at some point to have a content team for the website and help would be helpful here&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are interested in any of those actions please fill &lt;a class="reference external" href="https://framaforms.org/help-sarah-in-her-dsf-mission-1731706938"&gt;this form&lt;/a&gt;,
so I can reach you later if there are any specific needs.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="if-and-how-the-dsf-is-setting-and-tracking-goals-for-diversity-and-inclusion"&gt;
&lt;h2&gt;If and how the DSF is setting and tracking goals for diversity and inclusion?&lt;/h2&gt;
&lt;p&gt;We have a &lt;a class="reference external" href="https://www.djangoproject.com/diversity/"&gt;public statement for diversity&lt;/a&gt; and some ongoing DEI improvements.&lt;/p&gt;
&lt;p&gt;Currently it’s more to define what is the existing state and the evolution with statistics to be able to set goals.&lt;/p&gt;
&lt;p&gt;The actions that had been taken is mostly to show how diverse the community is in the Django world, which means:
the website, elections, the members and Django communication tools:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The local community page&lt;/li&gt;
&lt;li&gt;Recognize DSF members from all over the world&lt;/li&gt;
&lt;li&gt;Small initiatives to help to get a good representation of the diversity of the community in DSF board elections&lt;/li&gt;
&lt;li&gt;Talk about the current DSF members&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Could be even more, having Django participate in the &lt;a class="reference external" href="https://www.outreachy.org/"&gt;Outreachy program&lt;/a&gt; and so on.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-are-the-tasks-and-time-commitments"&gt;
&lt;h2&gt;What are the tasks and time commitments?&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Regular tasks as a baseline and then ad-hoc tasks/personal initiatives with rough times&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We have a meeting each month and it lasts one hour. During this time, we are reviewing all current and new business
with all members and the assistant Catherine.&lt;/p&gt;
&lt;p&gt;Except that, we have async communication on slack.&lt;/p&gt;
&lt;p&gt;Since I don't have a specific role, it's mostly promotion and representation of the Django Software Foundation and
following DSF working groups as a board of liaison. We have a contact form so I have to check emails and reply if
I can.&lt;/p&gt;
&lt;p&gt;In more ad-hoc tasks/personal initiatives, I don’t know precisely the time but I think it depends on the task,
if it’s research on a topic or doing something for a working group. I’m involved in 3 working groups,
which means that there might be meetings or actions that I may have to do related to that.&lt;/p&gt;
&lt;p&gt;It’s hard to explicitly define times, but I think I could say around 5+ hours a month, depending on the need and
my health.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-areas-do-you-think-the-board-could-improve-on-and-where-does-it-lack-skills-expertise"&gt;
&lt;h2&gt;What areas do you think the board could improve on and where does it lack skills/expertise?&lt;/h2&gt;
&lt;p&gt;I think the board could improve in promotion: get sponsors, offer sponsorship package in function of the level
of sponsoring, get contacts…&lt;/p&gt;
&lt;p&gt;And I believe in terms of legal considerations and marketing we are lacking expertise.
For example Django is known from developers for its stability and smooth upgrades, this is something
which is not promoted, or at least poorly by saying it’s “boring”.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="any-behind-the-curtain-stuff-any-pain-points"&gt;
&lt;h2&gt;Any &amp;quot;behind the curtain&amp;quot; stuff? Any pain points?&lt;/h2&gt;
&lt;p&gt;Should I really share behind the curtain stuff? 😁&lt;/p&gt;
&lt;p&gt;I think the major pain point for me was communication and documentation.&lt;/p&gt;
&lt;p&gt;Many things are not documented or partially and with all different boards I imagine things have been lost over time.
It’s hard to understand everything when you are new.&lt;/p&gt;
&lt;p&gt;Also, I would have preferred to have the tasks shared or potentially allow/push people to ask for help if no time
or whatever reason, especially when they have a role which can ask a lot.
It took me a lot of time to figure out who writes our news pages.
Access and the processes to ask for access are not always clear to me.
This kind of thing should be documented somewhere.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="how-does-the-board-decide-things-do-you-vote-on-everything"&gt;
&lt;h2&gt;How does the board decide things (do you vote on everything)?&lt;/h2&gt;
&lt;p&gt;As I was saying before, we have a board meeting each month and we have a precise agenda that we are reviewing
together:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Grant submissions&lt;/li&gt;
&lt;li&gt;DjangoCon proposal&lt;/li&gt;
&lt;li&gt;DSF memberships&lt;/li&gt;
&lt;li&gt;DSF working group&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of those areas are voted on each time if there is anything to vote on,
so we are making sure that we have a quorum before the start of the meeting, otherwise it will be rescheduled.
We also discuss things related to the DSF organisation like bylaws, trademark etc.
but things aren’t always under vote except if there is a major change.
All board members can add a topic to the agenda.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-things-folks-should-involve-the-board-with-and-what-can-they-just-do"&gt;
&lt;h2&gt;What things folks should involve the board with and what can they &amp;quot;just do&amp;quot;.&lt;/h2&gt;
&lt;p&gt;Some &lt;a class="reference external" href="https://github.com/django/dsf-working-groups"&gt;DSF working groups&lt;/a&gt; already exist, all members are identifiable and the way to join the working group.&lt;/p&gt;
&lt;p&gt;Everyone can help a working group without asking a board member.&lt;/p&gt;
&lt;p&gt;Everyone can create a DSF working group, but this needs at least one board member to follow and guide the
working group (=board liaison) with the DSF board vision and for reporting. When the proposal is ready,
the board liaison will bring it to the board meeting to be voted on by the board.&lt;/p&gt;
&lt;p&gt;There are also initiatives like Djangonaut Space, &lt;a class="reference external" href="https://django-news.com/"&gt;Django News&lt;/a&gt; etc. which don’t rely on the board at all,
if you have an idea which might solve something in the Django community, please do it!&lt;/p&gt;
&lt;p&gt;The major thing which involves the board is creating a new DjangoCon since the name is registered under
the Django trademark with certain criterias. You can still create smaller events without the board,
and some of them are registered in &lt;a class="reference external" href="https://www.djangoproject.com/community/local/"&gt;the local community page&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="your-personal-reflections-is-this-a-joy-or-a-chore"&gt;
&lt;h2&gt;Your personal reflections - is this a joy or a chore?&lt;/h2&gt;
&lt;p&gt;Hard to say, I have experienced both.&lt;/p&gt;
&lt;p&gt;I was frustrated to not be able to help in some cases or see people complaining but I didn’t get the information
at the board level directly where it could make a difference. So I keep notes and try to make changes but sometimes
it’s even just a matter of time or actions, it doesn’t go like you wanted and you’re disappointed with the result.&lt;/p&gt;
&lt;p&gt;I also enjoy people thanking me for some actions I have done, see them amazed with the DSF membership recognition
or just see people I know from other spaces (Djangonaut Space, Discord…) taking part in Django community contributions
in some way, even if it doesn’t end as expected like elections, this is really nice to see all folks from all over the
world gather for one thing in common.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="where-are-you-at-with-your-goals-are-we-on-track-if-we-aren-t-what-resources-would-it-take-to-accomplish-them"&gt;
&lt;h2&gt;Where are you at with your goals? Are we on track? If we aren't, what resources would it take to accomplish them.&lt;/h2&gt;
&lt;p&gt;If we retake &lt;a class="reference external" href="https://www.djangoproject.com/weblog/2023/nov/13/2024-dsf-board-candidates/"&gt;my personal statement from the Django blog post&lt;/a&gt;,
this is the current state:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;span class="underline"&gt;Increase fundraising&lt;/span&gt;: &lt;strong&gt;in progress&lt;/strong&gt; with DSF Fundraising WG
        &lt;ul&gt;
            &lt;li&gt;&lt;span class="underline"&gt;improving communication&lt;/span&gt;: ideas was shared with DSF social media WG, missing coordination with DSF Fundraising WG when the team have everything ready for&lt;/li&gt;
            &lt;li&gt;&lt;span class="underline"&gt;highlighting sponsors&lt;/span&gt;: this will be reviewed with the future DSF Website WG with coordination of DSF Fundraising WG&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;span class="underline"&gt;Develop our community&lt;/span&gt;:  &lt;strong&gt;in progress&lt;/strong&gt; with many new DSF members and newcomers
        &lt;ul&gt;
            &lt;li&gt;&lt;span class="underline"&gt;specifically helping existing and new contributor&lt;/span&gt;: sharing the community and meeting people in other events.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;span class="underline"&gt;Working group for mentorship&lt;/span&gt;: &lt;strong&gt;Discussion initiated&lt;/strong&gt;, I’m involved in too many working groups, I have now a volunteer to lead this project ✨ She will need people and resources to help her, an issue will be open soon, keep an eye on that.&lt;/li&gt;
    &lt;li&gt;&lt;span class="underline"&gt;Push accessibility in the framework&lt;/span&gt;: &lt;strong&gt;in progress&lt;/strong&gt;, we have new members and many ideas and discussions on going. This also rely a lot on DSF Website WG which will be soon kickstarted.&lt;/li&gt;
    &lt;li&gt;&lt;span class="underline"&gt;Django's diversity and expand the community&lt;/span&gt;: &lt;strong&gt;in progress&lt;/strong&gt;, have a better representation in Django like candidate elections or people shown in the website.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I believe we are on track but I can’t do that alone, especially for social media, we will need people to help us to promote and write content.&lt;/p&gt;
&lt;p&gt;There are also topics I would like to have more people involved in:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;DSF Code of Conduct WG&lt;/li&gt;
&lt;li&gt;Moderation of Discord and Forum&lt;/li&gt;
&lt;li&gt;Future team to write content of the website&lt;/li&gt;
&lt;li&gt;Get folks feedbacks in order to make improvements&lt;/li&gt;
&lt;li&gt;Get sponsors feedbacks&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="what-did-you-achieve"&gt;
&lt;h2&gt;What did you achieve?&lt;/h2&gt;
&lt;p&gt;I’m happy with what I have achieved, even though I was thinking I would have done more.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Represent DSF at some events (e.g. FOSDEM)&lt;/li&gt;
&lt;li&gt;Django booth at EuroPython&lt;/li&gt;
&lt;li&gt;DjangoCon Europe lightning talk&lt;/li&gt;
&lt;li&gt;DjangoCon Europe DSF panel&lt;/li&gt;
&lt;li&gt;Handle DSF roles on discord server&lt;/li&gt;
&lt;li&gt;Reply to some questions on discord, forum or email&lt;/li&gt;
&lt;li&gt;Help to quickstart the DSF Fundraising WG&lt;/li&gt;
&lt;li&gt;Add local communities in local communities page&lt;/li&gt;
&lt;li&gt;Follow-up on draft of the DSF Website WG&lt;/li&gt;
&lt;li&gt;Help on the review of DjangoCon proposal of next year&lt;/li&gt;
&lt;li&gt;Help the social media WG&lt;/li&gt;
&lt;li&gt;Research on the DSF past board and history&lt;/li&gt;
&lt;li&gt;Help on the next Django developer survey&lt;/li&gt;
&lt;li&gt;Submit many people for DSF membership&lt;/li&gt;
&lt;li&gt;Listing of potential requests that Djangonauts would like&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="what-would-you-like-to-achieve"&gt;
&lt;h2&gt;What would you like to achieve?&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Automate partially or completely the addition of new DSF Individual Members&lt;/li&gt;
&lt;li&gt;Improve fundraising to be able to take more actions&lt;/li&gt;
&lt;li&gt;Improve the website with the DSF Website WG&lt;/li&gt;
&lt;li&gt;Create a content website (WG?) team&lt;/li&gt;
&lt;li&gt;Create a mentorship / leadership WG&lt;/li&gt;
&lt;li&gt;Create a way to get feedback from the community&lt;/li&gt;
&lt;li&gt;Improve forms for futures elections&lt;/li&gt;
&lt;li&gt;Create a DSF members blog series&lt;/li&gt;
&lt;li&gt;Create some “did you know” social media post related to DSF&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="what-do-you-wish-the-community-knew-that-would-make-your-role-easier"&gt;
&lt;h2&gt;What do you wish the community knew that would make your role easier?&lt;/h2&gt;
&lt;p&gt;This is actually some time commitment if you want to do things outside of the monthly meeting.
Your work and extra activities take time and some days this is hard to work on open source.&lt;/p&gt;
&lt;p&gt;We need to increase funding but the best way to start is with you, dear lovely reader.
If you are working for a company, you should ask if they are sponsoring Django if they use it and tell them why they should do that.
If you don’t know what to tell for why, you can start by the fact it will help pay our Fellows,
the 2 incredible women who are maintaining the tool every day they are relying on and keep the security and improvements on it.&lt;/p&gt;
&lt;p&gt;Many things could be solved by having money, but not only. Sometimes what we are missing is people.
Having mentors, having people to answer questions, people who moderate platforms, people who contribute to code source.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-made-you-laugh"&gt;
&lt;h2&gt;What made you laugh?&lt;/h2&gt;
&lt;p&gt;My onboarding, it was definitely not what I expected, even if I didn’t expect so much to be honest.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="would-you-do-it-again"&gt;
&lt;h2&gt;Would you do it again?&lt;/h2&gt;
&lt;p&gt;I think yes, not because this is particularly fun, but more because some things can change only at some level,
and I think I can be helpful here.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="if-you-had-impostor-syndrome-how-do-you-deal-with-it"&gt;
&lt;h2&gt;If you had impostor syndrome, how do you deal with it?&lt;/h2&gt;
&lt;p&gt;Impostor syndrome is, unfortunately, my best friend, always there I don’t know why lol&lt;/p&gt;
&lt;p&gt;I think it's a question of thinking about the best way, even if I'm not the most competent person,
I think I have something to contribute, and that's why I was elected.&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="dsf"/><category term="django"/></entry><entry><title>TIL : ressources sur l'accessibilité #2</title><link href="https://sarahabd.com/fr/til/accessibility-resources-second-edition" rel="alternate"/><published>2024-05-23T00:00:00+02:00</published><updated>2024-05-23T00:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2024-05-23:/fr/til/accessibility-resources-second-edition</id><summary type="html">&lt;p class="first last"&gt;Bonjour, j'ai décidé de faire une deuxième édition des ressources sur l'accessibilité.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour,&lt;/p&gt;
&lt;p&gt;J'ai décidé de lancer une deuxième édition des ressources sur l'accessibilité.
J'ai appris beaucoup de choses sur l'accessibilité et je veux partager ces ressources avec vous.
Je les ai classées par thème, selon ce qui pourrait vous intéresser le plus.&lt;/p&gt;
&lt;div class="section" id="cours"&gt;
&lt;h2&gt;Cours&lt;/h2&gt;
&lt;p&gt;Ces cours sont intéressants pour une introduction à l'accessibilité et pour revoir certains concepts si vous connaissez déjà les notions d'accessibilité.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.edx.org/learn/web-accessibility/the-world-wide-web-consortium-w3c-introduction-to-web-accessibility"&gt;Cours edX : Introduction to Web Accessibility&lt;/a&gt; - cours gratuit&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://practical-accessibility.today/"&gt;Cours de Sara Soueidan : Practical Accessibility&lt;/a&gt; - cours payant&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="livres"&gt;
&lt;h2&gt;Livres&lt;/h2&gt;
&lt;p&gt;Je suis une grande fan des livres numériques, je les ai tous dans ce format si c'est important pour vous.
Je n'ai pas tout lu, mais ceux que je n'ai pas terminés sont dans ma liste de choses à faire.
J'ai ajouté des liens pour les personnes qui veulent en savoir plus, mais vous pouvez les trouver sur d'autres plateformes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://abookapart.com/products/accessibility-for-everyone"&gt;Accessibility for everyone&lt;/a&gt;, Laura Kalbag - A Book Apart&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.amazon.com/Maximum-Accessibility-Making-Usable-Everyone/dp/0201774224"&gt;Maximum Accessibility: Making Your Web Site More Usable for Everyone: Making Your Web Site More Usable for Everyone&lt;/a&gt;, Sharron Rush  - Amazon&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.amazon.com/Practical-Web-Inclusion-Accessibility-Comprehensive/dp/1484254511"&gt;Practical Web Inclusion and Accessibility: A Comprehensive Guide to Access Needs&lt;/a&gt;, Ashley Firth - Amazon&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.amazon.com/Web-Accessibility-Cookbook-Inclusive-Experiences/dp/1098145607"&gt;Web Accessibility Cookbook: Creating Inclusive Experiences&lt;/a&gt;, Manuel Matuzovic - Amazon&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.amazon.com/Beyond-Accessibility-Compliance-Generation-Inclusive/dp/1484279476"&gt;Beyond Accessibility Compliance: Building the Next Generation of Inclusive Products&lt;/a&gt;, Sukriti Chadha - Amazon&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.amazon.com/Fixing-Access-Annoyances-Phil-Mitchell/dp/059600852X"&gt;Fixing Access Annoyances&lt;/a&gt;, Phil Mitchell - Amazon&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.amazon.com/Web-Accessibility-Standards-Regulatory-Compliance/dp/1590596382"&gt;Web Accessibility: Web Standards and Regulatory Compliance&lt;/a&gt;, Jim Thatcher, Mark Urban, Bruce Lawson, Michael R. Burks, Richard Rutter, Andrew Kirkpatrick, Christian Heilmann, Shawn Lawton Henry, Bob Regan, Cynthia D. Waddell - Amazon&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.amazon.com/Ensuring-Digital-Accessibility-through-Process/dp/0128006463"&gt;Ensuring Digital Accessibility through Process and Policy&lt;/a&gt;, Jonathan Lazar, Daniel F. Goldstein, Anne Taylor - Amazon&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="couleurs-et-contraste"&gt;
&lt;h2&gt;Couleurs et contraste&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.whocanuse.com/"&gt;Vérificateur de couleurs whocanuse&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://contrast-grid.eightshapes.com/"&gt;Grille de contraste d'eightshapes.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://chrome.google.com/webstore/detail/colorblindly/floniaahmccleoclneebhhmnjgdfijgg"&gt;Extension Chrome Colorblindly&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il existe beaucoup de super comptes et ressources partagés via &lt;strong&gt;#a11y&lt;/strong&gt; ou &lt;strong&gt;#accessibility&lt;/strong&gt;, ça vaut le coup de les suivre sur les réseaux sociaux.&lt;/p&gt;
&lt;p&gt;C'est tout pour le moment ! J'espère que ça sera utile à quelqu'un.&lt;/p&gt;
&lt;/div&gt;
</content><category term="til"/><category term="til"/><category term="accessibility"/><category term="resources"/></entry><entry><title>TIL: Accessibility resources #2</title><link href="https://sarahabd.com/til/accessibility-resources-second-edition" rel="alternate"/><published>2024-05-23T00:00:00+02:00</published><updated>2024-05-23T00:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2024-05-23:/til/accessibility-resources-second-edition</id><summary type="html">&lt;p class="first last"&gt;Hi there, I decided to a second edition of accessibility resources.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi there,&lt;/p&gt;
&lt;p&gt;I decided to start a second edition of accessibility resources,
I have learned many things about accessibility and I want to share these resources with you.
I have made sections related on topic you might be more interested.&lt;/p&gt;
&lt;div class="section" id="courses"&gt;
&lt;h2&gt;Courses&lt;/h2&gt;
&lt;p&gt;These courses are interesting as an introduction to accessibility and to review certain concepts if you are already familiar with accessibility notions.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.edx.org/learn/web-accessibility/the-world-wide-web-consortium-w3c-introduction-to-web-accessibility"&gt;Edx course: Introduction to Web Accessibility&lt;/a&gt; - Free course&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://practical-accessibility.today/"&gt;Sara Soueidan course: Practical Accessibility&lt;/a&gt; - Paid course&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="books"&gt;
&lt;h2&gt;Books&lt;/h2&gt;
&lt;p&gt;I'm a big fan of ebooks, I have all of them in that format if it's a requirement for you.
I haven't read everything but it's on my todo-list if not finished.
I added some links for people who wants to learn more but you can find them in other platforms.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://abookapart.com/products/accessibility-for-everyone"&gt;Accessibility for everyone&lt;/a&gt;, Laura Kalbag - A book A Part&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.amazon.com/Maximum-Accessibility-Making-Usable-Everyone/dp/0201774224"&gt;Maximum Accessibility: Making Your Web Site More Usable for Everyone: Making Your Web Site More Usable for Everyone&lt;/a&gt;, Sharron Rush  - Amazon&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.amazon.com/Practical-Web-Inclusion-Accessibility-Comprehensive/dp/1484254511"&gt;Practical Web Inclusion and Accessibility: A Comprehensive Guide to Access Needs&lt;/a&gt;, Ashley Firth - Amazon&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.amazon.com/Web-Accessibility-Cookbook-Inclusive-Experiences/dp/1098145607"&gt;Web Accessibility Cookbook: Creating Inclusive Experiences&lt;/a&gt;, Manuel Matuzovic - Amazon&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.amazon.com/Beyond-Accessibility-Compliance-Generation-Inclusive/dp/1484279476"&gt;Beyond Accessibility Compliance: Building the Next Generation of Inclusive Products&lt;/a&gt;, Sukriti Chadha - Amazon&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.amazon.com/Fixing-Access-Annoyances-Phil-Mitchell/dp/059600852X"&gt;Fixing Access Annoyances&lt;/a&gt;, Phil Mitchell - Amazon&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.amazon.com/Web-Accessibility-Standards-Regulatory-Compliance/dp/1590596382"&gt;Web Accessibility: Web Standards and Regulatory Compliance&lt;/a&gt;, Jim Thatcher, Mark Urban, Bruce Lawson, Michael R. Burks, Richard Rutter, Andrew Kirkpatrick, Christian Heilmann, Shawn Lawton Henry, Bob Regan, Cynthia D. Waddell - Amazon&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.amazon.com/Ensuring-Digital-Accessibility-through-Process/dp/0128006463"&gt;Ensuring Digital Accessibility through Process and Policy&lt;/a&gt;, Jonathan Lazar, Daniel F. Goldstein, Anne Taylor - Amazon&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="colors-and-contrast"&gt;
&lt;h2&gt;Colors and contrast&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.whocanuse.com/"&gt;Color checker whocanuse&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://contrast-grid.eightshapes.com/"&gt;Contrast grid matrix from eightshapes.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://chrome.google.com/webstore/detail/colorblindly/floniaahmccleoclneebhhmnjgdfijgg"&gt;Colorblindly chrome extension&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are many great accounts and resources shared via &lt;strong&gt;#a11y&lt;/strong&gt; or &lt;strong&gt;#accessibility&lt;/strong&gt;, worth to follow them in social medias.&lt;/p&gt;
&lt;p&gt;That’s it for now! I hope it will be useful for someone.&lt;/p&gt;
&lt;/div&gt;
</content><category term="til"/><category term="til"/><category term="accessibility"/><category term="resources"/></entry><entry><title>TIL : git push force with lease</title><link href="https://sarahabd.com/fr/til/git-push-force-with-lease" rel="alternate"/><published>2024-05-22T11:00:00+02:00</published><updated>2024-05-22T11:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2024-05-22:/fr/til/git-push-force-with-lease</id><summary type="html">&lt;p class="first last"&gt;Git push force with lease, ma nouvelle meilleure amie.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour,&lt;/p&gt;
&lt;p&gt;J'ai l'habitude de rebaser mes PR avec un git rebase puis un force push, et j'ai découvert ma nouvelle meilleure amie : &lt;cite&gt;git push --force-with-lease&lt;/cite&gt;, grâce à mes collègues.&lt;/p&gt;
&lt;div class="section" id="git-rebase"&gt;
&lt;h2&gt;Git rebase ?&lt;/h2&gt;
&lt;p&gt;Git rebase permet de réécrire l'historique des commits d'une branche donnée. Vous pouvez consulter la &lt;a class="reference external" href="https://git-scm.com/docs/git-push"&gt;documentation complète de git push&lt;/a&gt;.
Si vous débutez ou si vous n'êtes pas encore à l'aise avec git, j'aime beaucoup &lt;a class="reference external" href="https://learngitbranching.js.org/"&gt;ce site&lt;/a&gt; pour apprendre git et pratiquer en même temps.
Vous pouvez réécrire l'historique de vos commits puis faire un force push.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="force-vs-force-with-lease"&gt;
&lt;h2&gt;&lt;cite&gt;--force&lt;/cite&gt; vs &lt;cite&gt;--force-with-lease&lt;/cite&gt;&lt;/h2&gt;
&lt;p&gt;La différence entre &lt;cite&gt;--force&lt;/cite&gt; et &lt;cite&gt;--force-with-lease&lt;/cite&gt;, c'est qu'avec &lt;cite&gt;--force-with-lease&lt;/cite&gt;, le push ne se fera que si vous n'écrasez aucun travail sur
la branche distante, dans le cas où d'autres commits y auraient été ajoutés. Si c'est le cas, le push sera annulé et vous obtiendrez une erreur.&lt;/p&gt;
&lt;p&gt;&lt;cite&gt;--force&lt;/cite&gt; écrasera tout le travail présent sur la branche distante, qu'il y ait du nouveau ou non. Comme vous pouvez le voir, &lt;cite&gt;--force-with-lease&lt;/cite&gt;
est une option plus sûre si vous ne voulez pas écraser le travail de quelqu'un d'autre en faisant un force push.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="bonus-force-if-includes"&gt;
&lt;h2&gt;Bonus : &lt;cite&gt;--force-if-includes&lt;/cite&gt;&lt;/h2&gt;
&lt;p&gt;J'ai découvert aujourd'hui via Mastodon qu'&lt;a class="reference external" href="https://adamj.eu/"&gt;Adam Johnson&lt;/a&gt; avait écrit un article sur le sujet avant celui-ci, il vaut le détour. J'y ai aussi découvert
&lt;cite&gt;--force-if-includes&lt;/cite&gt; : &lt;a class="reference external" href="https://adamj.eu/tech/2023/10/31/git-force-push-safely/"&gt;vous pouvez en apprendre plus dans son article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;C'est tout pour le moment ! J'espère que ça sera utile à quelqu'un.&lt;/p&gt;
&lt;/div&gt;
</content><category term="til"/><category term="til"/><category term="git"/></entry><entry><title>TIL: Git push force with lease</title><link href="https://sarahabd.com/til/git-push-force-with-lease" rel="alternate"/><published>2024-05-22T11:00:00+02:00</published><updated>2024-05-22T11:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2024-05-22:/til/git-push-force-with-lease</id><summary type="html">&lt;p class="first last"&gt;Git push force with lease, my new friend.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi there,&lt;/p&gt;
&lt;p&gt;I'm used to rebase my PRs with a git rebase and force push, I discovered my new friend: &lt;cite&gt;git push --force-with-lease&lt;/cite&gt; thanks to my coworkers.&lt;/p&gt;
&lt;div class="section" id="git-rebase"&gt;
&lt;h2&gt;Git rebase?&lt;/h2&gt;
&lt;p&gt;Git rebase is helpful to rewrite history of the commits in a specific branch. You have the &lt;a class="reference external" href="https://git-scm.com/docs/git-push"&gt;full documentation of git push&lt;/a&gt;.
If you are new or not fully familiar to git, I quite like &lt;a class="reference external" href="https://learngitbranching.js.org/"&gt;this website&lt;/a&gt; in order to to learn git and practice at the same time.
You can rewrite the history of your commits and then force push.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="force-vs-force-with-lease"&gt;
&lt;h2&gt;&lt;cite&gt;--force&lt;/cite&gt; vs &lt;cite&gt;--force-with-lease&lt;/cite&gt;&lt;/h2&gt;
&lt;p&gt;The difference between &lt;cite&gt;--force&lt;/cite&gt; and &lt;cite&gt;--force-with-lease&lt;/cite&gt; is with &lt;cite&gt;--force-with-lease&lt;/cite&gt; will push only if you are not overwriting any work on
the remote branch if more commits were added to the remote branch. If is not the case, the push will be cancelled and you will get an error.&lt;/p&gt;
&lt;p&gt;&lt;cite&gt;--force&lt;/cite&gt; will overwrite any work in the remote branch, no matter if there are anything new in the branch. As you can see, &lt;cite&gt;--force-with-lease&lt;/cite&gt;
is a safer option if you don't want to overwrite someone elses work by force pushing.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="bonus-force-if-includes"&gt;
&lt;h2&gt;Bonus: &lt;cite&gt;--force-if-includes&lt;/cite&gt;&lt;/h2&gt;
&lt;p&gt;I discovered today via Mastodon that &lt;a class="reference external" href="https://adamj.eu/"&gt;Adam Johnson&lt;/a&gt; has done a post related to this before this one, worth take a look, I also learned about
&lt;cite&gt;--force-if-includes&lt;/cite&gt; : &lt;a class="reference external" href="https://adamj.eu/tech/2023/10/31/git-force-push-safely/"&gt;you can learn more on his article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;That’s it for now! I hope it will be useful for someone.&lt;/p&gt;
&lt;/div&gt;
</content><category term="til"/><category term="til"/><category term="git"/></entry><entry><title>Ma checklist de revue d'accessibilité</title><link href="https://sarahabd.com/fr/blog/my-accessibility-review-checklist" rel="alternate"/><published>2024-03-27T10:00:00+01:00</published><updated>2024-03-27T10:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2024-03-27:/fr/blog/my-accessibility-review-checklist</id><summary type="html">&lt;p class="first last"&gt;Ma checklist de revue d'accessibilité et d'autres checklists&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour, certain·es d'entre vous savent déjà que je m'intéresse à l'accessibilité
et que je contribue à des projets open source dans ce domaine. Je voulais écrire
une checklist pour me rappeler les points à vérifier quand je relis une PR,
afin de ne rien oublier. C'est mon point de vue, et j'apprends encore
énormément sur l'accessibilité. Ça pourrait vous être utile si vous
voulez faire de même. Je mettrai aussi des liens vers d'autres checklists, car beaucoup
de choses existaient déjà avant que j'écrive cet article, et elles sont géniales.&lt;/p&gt;
&lt;p&gt;Si vous avez un doute sur quoi que ce soit, vous pouvez consulter la documentation :&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.w3.org/WAI/standards-guidelines/wcag/fr"&gt;Règles pour l'accessibilité des contenus web (WCAG)&lt;/a&gt;&lt;/p&gt;
&lt;div class="section" id="tl-dr"&gt;
&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;Voici le résumé des points de la checklist à surveiller :&lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox1" class="form-control"&gt;&lt;input type="checkbox" id="checkbox1" name="checkbox1"&gt;1.Tester avec des outils de vérification d'accessibilité&lt;/label&gt; &lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox2" class="form-control"&gt;&lt;input type="checkbox" id="checkbox2" name="checkbox2"&gt;2.Utiliser du HTML sémantique&lt;/label&gt; &lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox3" class="form-control"&gt;&lt;input type="checkbox" id="checkbox3" name="checkbox3"&gt;3.Utiliser un texte alternatif approprié pour toutes les images et icônes&lt;/label&gt; &lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox4" class="form-control"&gt;&lt;input type="checkbox" id="checkbox4" name="checkbox4"&gt;4.S'assurer que la navigation au clavier est possible&lt;/label&gt; &lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox5" class="form-control"&gt;&lt;input type="checkbox" id="checkbox5" name="checkbox5"&gt;5.S'assurer que le contraste des couleurs respecte les normes d'accessibilité&lt;/label&gt;&lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox6" class="form-control"&gt;&lt;input type="checkbox" id="checkbox6" name="checkbox6"&gt;6.Vérifier le bon usage des attributs ARIA&lt;/label&gt;&lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox7" class="form-control"&gt;&lt;input type="checkbox" id="checkbox7" name="checkbox7"&gt;7.Ajouter des landmarks&lt;/label&gt;&lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox8" class="form-control"&gt;&lt;input type="checkbox" id="checkbox8" name="checkbox8"&gt;8.Tester avec des lecteurs d'écran&lt;/label&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div class="section" id="la-checklist-detaillee"&gt;
&lt;h2&gt;La checklist détaillée&lt;/h2&gt;
&lt;div class="section" id="outils-de-verification-d-accessibilite"&gt;
&lt;h3&gt;Outils de vérification d'accessibilité&lt;/h3&gt;
&lt;p&gt;Tester est la partie la plus importante. Même si vous ne connaissez pas
tout de l'accessibilité, vous saurez ce qui ne va pas et ce que vous
avez réellement fait, et vous pourrez commencer à améliorer les choses quelque part.&lt;/p&gt;
&lt;p&gt;Il existe de nombreux outils qui permettent de tester correctement votre code et
de vous donner des indications sur la règle et/ou le code à modifier.&lt;/p&gt;
&lt;p&gt;Il y a plusieurs façons de tester un site. D'abord, il y a les outils
de vérification d'accessibilité. Vous pouvez les utiliser via une extension de navigateur, directement via
leur site, ou les intégrer comme outil dans votre projet.&lt;/p&gt;
&lt;p&gt;N'oubliez pas que vous pouvez aussi utiliser les outils de développement, qui proposent certaines vérifications
liées à l'accessibilité. Par exemple, vous pouvez forcer les couleurs du thème pour voir
les changements. Personnellement, j'utilise l'extension de navigateur &lt;a class="reference external" href="https://accessibilityinsights.io/downloads/"&gt;Accessibility
Insights&lt;/a&gt;. Elle répond à mes
besoins la plupart du temps et c'est un outil très complet.&lt;/p&gt;
&lt;p&gt;Pour éviter de réinventer la roue, je vous conseille d'en apprendre plus sur la façon de
&lt;a class="reference external" href="https://a11y.coffee/start-testing/"&gt;commencer à tester l'accessibilité avec l'article de
a11y.coffee&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Si vous voulez automatiser certains tests, c'est aussi
possible.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;« 57,38 % du total des problèmes ont été détectés lors de tests automatisés »&lt;/em&gt;,
selon &lt;a class="reference external" href="https://www.deque.com/automated-accessibility-testing-coverage/"&gt;Deque, vous trouverez plus d'informations sur leur
site&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pa11y est un excellent outil pour automatiser vos tests d'accessibilité : il existe
Pa11y CI, conçu pour fonctionner en intégration continue. Vous pouvez
trouver &lt;a class="reference external" href="https://pa11y.org/tutorials/"&gt;de nombreux tutoriels sur Pa11y&lt;/a&gt; sur leur
site.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="balisage-html"&gt;
&lt;h3&gt;Balisage HTML&lt;/h3&gt;
&lt;p&gt;C'est quelque chose auquel on pense rarement, mais ça a un impact sur
l'accessibilité. Les balises div et span n'ont aucune signification sémantique, et
c'est vraiment important. Les éléments sémantiques sont reconnus par les navigateurs,
mais aussi par les lecteurs d'écran et les autres technologies d'assistance. Je crois que je
ne pourrais pas expliquer mieux leur importance que l'article &lt;a class="reference external" href="https://accessibilitywise.info/semantic-code-why-meaning-is-important/essentials/"&gt;Semantic Code. Why
meaning is
important&lt;/a&gt;
d'&lt;a class="reference external" href="http://accessibiltywise.info/"&gt;accessibiltywise.info&lt;/a&gt;, par
Edward Haynes.&lt;/p&gt;
&lt;p&gt;Par exemple, pour décrire une liste non ordonnée, au lieu d'utiliser ce
code :&lt;/p&gt;
&lt;pre class="code html literal-block"&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Coffee&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tea&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Water&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Vous pourriez utiliser ces éléments HTML spécifiques :&lt;/p&gt;
&lt;pre class="code html literal-block"&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Coffee&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tea&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Water&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="texte-alternatif"&gt;
&lt;h3&gt;Texte alternatif&lt;/h3&gt;
&lt;p&gt;Les images et les icônes sont jolies et esthétiques, mais elles n'ont aucun sens pour les personnes
malvoyantes ou aveugles.&lt;/p&gt;
&lt;p&gt;Beaucoup d'outils et de sites intègrent un texte alternatif pour que
les personnes qui ne voient pas l'image, ou qui ont du mal à la voir, aient au
moins sa description. La plupart du temps, c'est une courte
description, mais c'est mieux que rien.&lt;/p&gt;
&lt;p&gt;Sur le site, vérifiez que chaque média, en particulier les images, a un attribut alt.&lt;/p&gt;
&lt;p&gt;Par exemple, pour ajouter la photo de l'entreprise sur une page, vous pourriez faire
quelque chose comme ceci :&lt;/p&gt;
&lt;pre class="code html literal-block"&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt;
   &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/path/to/img&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Photo of the Company Staff holding a flag&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Pour prendre un vrai cas d'usage, j'ai pris une image de mon blog ci-dessous : si l'image
n'est pas accessible ou si le lien est simplement cassé, on obtient ce
résultat, comme vous pouvez le voir ci-dessous :&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="rendu d'une image cassée avec un texte alternatif" src="/images/image-result-for-alternative-text.png" /&gt;
&lt;p class="caption"&gt;Rendu d'une image cassée avec un texte alternatif&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="labels"&gt;
&lt;h3&gt;Labels&lt;/h3&gt;
&lt;p&gt;Souvent, les gens aiment se passer des labels ou les supprimer. Pour le design ou pour une autre
raison, vous ne devriez pas le faire. Les labels visibles aident à savoir ce que
représente un élément. C'est particulièrement important dans un formulaire,
par exemple. Un exemple concret est le placeholder d'un champ de
carte bancaire :&lt;/p&gt;
&lt;blockquote cite="https://twitter.com/SaraSoueidan/status/1577941158491201537"&gt;
   &lt;p&gt;Utiliser un placeholder sans label sur le champ de la carte bancaire, par
exemple, fait dire au lecteur d'écran « kisses kisses kisses kisses » (car le
placeholder est xxxx-xxxx-xxxx-xxxx) au lieu de « numéro de carte bancaire »&lt;/p&gt;
   &lt;footer&gt;—Sara Soueidan, &lt;cite&gt;Twitter&lt;/cite&gt;&lt;/footer&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a class="reference external" href="https://twitter.com/SaraSoueidan/status/1578346744550543360"&gt;L'enregistrement du lecteur d'écran est disponible.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Dans ce cas, le mieux serait d'ajouter un label relié au champ avec
l'attribut for, comme ceci :&lt;/p&gt;
&lt;pre class="code html literal-block"&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;cardNumber&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Card Number&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
   &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;cardNumber&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;inputmode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;numeric&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;[0-9]*&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Il est possible d'ajouter une indication si besoin avec une balise span. Les gens devraient
pouvoir saisir leur numéro de carte bancaire dans le format qui leur est
familier. Cela veut dire pouvoir ajouter des espaces, des traits d'union et
des tirets, tout en permettant de valider le bon format du
champ.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="navigation-au-clavier"&gt;
&lt;h3&gt;Navigation au clavier&lt;/h3&gt;
&lt;p&gt;Naviguer sur un site peut être difficile si on n'aide pas les lecteurs et lectrices,
surtout quand ils utilisent uniquement un clavier et/ou un lecteur d'écran. C'est
pourquoi il faut utiliser le bon balisage HTML et réfléchir à la
navigation. Le meilleur moyen est d'essayer de naviguer comme le ferait quelqu'un d'autre.&lt;/p&gt;
&lt;p&gt;Vous remarquerez aussi l'importance de l'indicateur de focus dans ce type
de navigation, pour savoir sur quel élément vous vous trouvez. Si
vous avez un jour supprimé l'outline des éléments en CSS sans
définir de nouvel indicateur, reconsidérez-le maintenant que vous savez ça.&lt;/p&gt;
&lt;p&gt;Voici les étapes pour naviguer sur un site :&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Parcourez votre page avec la touche Tab&lt;/li&gt;
&lt;li&gt;Assurez-vous que chaque élément interactif peut être atteint.&lt;/li&gt;
&lt;li&gt;Assurez-vous que chaque élément interactif peut être utilisé.&lt;/li&gt;
&lt;li&gt;Assurez-vous que l'ordre est logique.&lt;/li&gt;
&lt;li&gt;Assurez-vous que le focus est visible, non masqué et suffisamment contrasté.&lt;/li&gt;
&lt;li&gt;Faites la même chose dans l'autre sens avec Maj + Tab&lt;/li&gt;
&lt;li&gt;Assurez-vous qu'il n'y a pas de piège au focus&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;La navigation est censée suivre un ordre logique entre les éléments. Si vous voyez
quelque chose qui ne va pas, vous pouvez chercher comment le corriger. Cette partie est plus facile
quand vous avez des retours ou que vous demandez à d'autres personnes de vérifier que tout est correct.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="couleurs-et-contraste"&gt;
&lt;h3&gt;Couleurs et contraste&lt;/h3&gt;
&lt;p&gt;Les couleurs et le contraste ont un impact sur beaucoup d'utilisateurs et d'utilisatrices :
handicaps, confort de lecture la nuit, basse vision, etc. C'est
important, car c'est la première chose qu'on voit en plus du
contenu. Un faible contraste rend les choses difficiles à distinguer et à lire,
en particulier pour les personnes ayant une faible acuité visuelle ou un daltonisme.&lt;/p&gt;
&lt;p&gt;Il existe de nombreuses façons de s'assurer que le contraste est suffisant et que tout le monde peut
lire. Les devtools de votre navigateur vous aident à vérifier
directement les éléments qui ont une couleur et/ou un arrière-plan.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Contraste des couleurs avec les devtools de Chrome sur djangoproject.com" src="/images/devtools-chrome-contrast.png" /&gt;
&lt;p class="caption"&gt;Contraste des couleurs d'un texte de la barre latérale avec les devtools de Chrome sur djangoproject.com&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Vous pouvez aussi ajouter une extension à votre navigateur pour vérifier
les couleurs et le contraste. Par exemple, j'utilise personnellement
&lt;a class="reference external" href="https://chrome.google.com/webstore/detail/colorblindly/floniaahmccleoclneebhhmnjgdfijgg"&gt;colorblindly&lt;/a&gt;
sur Chrome pour voir les différences entre les types de vision des couleurs qui peuvent
exister.&lt;/p&gt;
&lt;p&gt;Enfin, il existe des sites ou des outils dédiés qui vous aident à
vérifier le contraste pour des cas précis. J'aime beaucoup &lt;a class="reference external" href="https://www.whocanuse.com/"&gt;whocanuse.com&lt;/a&gt;
pour voir les différents types de vision entre une couleur et la couleur d'arrière-plan
associée.&lt;/p&gt;
&lt;p&gt;Si vous voulez comparer deux couleurs avec une matrice, &lt;a class="reference external" href="https://contrast-grid.eightshapes.com/"&gt;contrast-grid
d'eightshapes.com&lt;/a&gt; est mon outil de référence.&lt;/p&gt;
&lt;p&gt;Il existe des outils spécifiques qui vous aident à adapter la couleur en fonction
de l'image, par exemple. On le voit sur les réseaux sociaux, comme
Instagram : le texte sur un arrière-plan sera blanc ou noir selon
la couleur, pour garantir un contraste correct.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="attributs-aria"&gt;
&lt;h3&gt;Attributs ARIA&lt;/h3&gt;
&lt;p&gt;ARIA est l'abréviation d'Accessible Rich Internet Applications. C'est
utile pour fournir des informations accessibles en complément de la sémantique
HTML, mais ça ne doit être utilisé que lorsque c'est nécessaire.&lt;/p&gt;
&lt;p&gt;Par exemple, c'est quelque chose à utiliser pour indiquer l'élément
courant : page, section... Un bon exemple est le fil d'Ariane :&lt;/p&gt;
&lt;pre class="code html literal-block"&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt; &lt;span class="na"&gt;aria-label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;breadcrumbs&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/blog&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Blog&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;
            &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/blog/accessibility&amp;quot;&lt;/span&gt;
            &lt;span class="na"&gt;aria-current&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;page&amp;quot;&lt;/span&gt;
         &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            Accessibility
         &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Le risque avec ARIA, c'est que les gens pensent qu'il faut à chaque fois ajouter un
attribut, et ce n'est pas le cas. La sémantique HTML peut suffire dans
certains cas. Par exemple, une balise button n'a pas besoin d'avoir un rôle, elle
a automatiquement le rôle button. Vous trouverez plus d'informations sur les rôles
ARIA sur le &lt;a class="reference external" href="https://developer.mozilla.org/fr/docs/Web/Accessibility/ARIA/Roles"&gt;site
MDN&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="landmarks"&gt;
&lt;h3&gt;Landmarks&lt;/h3&gt;
&lt;p&gt;Les landmarks (ou points de repère) sont les « sections » qui structurent le site : header, main,
footer, nav...&lt;/p&gt;
&lt;p&gt;Ils peuvent être définis via les balises HTML : main a sa propre balise, ce qui
permet de définir le contenu principal de la page.&lt;/p&gt;
&lt;p&gt;Les landmarks sont particulièrement utiles pour structurer la page, mais aussi pour passer
facilement d'une section à l'autre avec un lecteur d'écran.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="landmarks sur le site djangoproject.com" src="/images/landmarks.png" /&gt;
&lt;p class="caption"&gt;Landmarks affichés avec des carrés sur djangoproject.com avec Accessibility Insights*&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Une chose à ne pas oublier : si un même type de landmark est utilisé plusieurs
fois, par exemple &lt;cite&gt;&amp;lt;nav&amp;gt;&lt;/cite&gt; pour le landmark de navigation, chaque occurrence
a besoin d'un &lt;cite&gt;aria-label&lt;/cite&gt; pour les distinguer.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="lecteurs-d-ecran"&gt;
&lt;h3&gt;Lecteurs d'écran&lt;/h3&gt;
&lt;p&gt;Les lecteurs d'écran sont très utiles pour les personnes en situation de handicap ou
qui préfèrent les utiliser pour se faciliter la vie. Beaucoup pensent que c'est uniquement
pour les personnes aveugles, mais ce n'est pas le cas. Une personne dyslexique peut utiliser un
lecteur d'écran sur son ordinateur, tout comme une personne ayant des troubles de la motricité,
même temporaires par exemple. Le lecteur d'écran annonce le contenu d'un
site via la synthèse vocale ou sur une plage braille. Il propose aussi plusieurs
façons d'interagir avec le site au clavier, il ne s'agit pas seulement de lire le
contenu : remplir un formulaire, interagir avec le navigateur, etc.&lt;/p&gt;
&lt;p&gt;Il existe différents lecteurs d'écran selon l'appareil ou le navigateur
pris en charge et les fonctionnalités. JAWS et NVDA sont les plus populaires.
VoiceOver est celui installé par défaut sur les appareils Apple. Les systèmes
d'exploitation Microsoft utilisent le Narrateur. Les appareils Android proposent le lecteur
d'écran TalkBack ou VoiceView par défaut. Pour les systèmes Linux et Unix, il y a
Orca ou SpeakUp. Vous devriez pouvoir trouver un lecteur d'écran pour
votre appareil.&lt;/p&gt;
&lt;p&gt;Il suffit d'essayer de vous mettre à la place de quelqu'un qui ne voit pas
parfaitement le site et de le parcourir avec l'outil.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Pour résumer, cette checklist de revue d'accessibilité est un bon moyen
d'initier les gens à l'accessibilité et de relire vos propres sites pour corriger les erreurs
qui pourraient empêcher des personnes de les utiliser. C'est ma propre
checklist, mais il en existe beaucoup d'autres très bien, vous pouvez jeter un œil
à la liste ci-dessous.&lt;/p&gt;
&lt;p&gt;Un grand merci aux personnes qui ont relu cet article, elles se reconnaîtront.
Merci pour votre soutien 💚&lt;/p&gt;
&lt;p&gt;-- Que le futur soit accessible grâce à ces checklists ⭐&lt;/p&gt;
&lt;div class="section" id="autres-checklists"&gt;
&lt;h4&gt;Autres checklists&lt;/h4&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.magentaa11y.com/"&gt;https://www.magentaa11y.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.a11yproject.com/checklist/"&gt;https://www.a11yproject.com/checklist/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://webaim.org/standards/wcag/checklist"&gt;https://webaim.org/standards/wcag/checklist&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://webflow.com/accessibility/checklist#start"&gt;https://webflow.com/accessibility/checklist#start&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://dequeuniversity.com/checklists/web/"&gt;https://dequeuniversity.com/checklists/web/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="accessibility"/><category term="resources"/></entry><entry><title>My Accessibility Review Checklist</title><link href="https://sarahabd.com/blog/my-accessibility-review-checklist" rel="alternate"/><published>2024-03-27T10:00:00+01:00</published><updated>2024-03-27T10:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2024-03-27:/blog/my-accessibility-review-checklist</id><summary type="html">&lt;p class="first last"&gt;My accessibility review checklist and others checklists&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi there, some of you already know I have an interest in accessibility
and contribute to open source projects in this domain. I wanted to write
a checklist to remind myself of things to check when I’m reviewing a PR
to avoid forgetting elements. This is from my point of view and I’m
still learning a lot about accessibility. This might be useful if you
want to do so too. I will also link to other checklists because many
things already exist before I write this article and they are awesome.&lt;/p&gt;
&lt;p&gt;If you have doubts for anything, you can check in the documentation:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.w3.org/WAI/standards-guidelines/wcag/"&gt;Web Content Accessibility Guidelines (WCAG)&lt;/a&gt;&lt;/p&gt;
&lt;div class="section" id="tl-dr"&gt;
&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;Here you have the summary of the checklist to care about:&lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox1" class="form-control"&gt;&lt;input type="checkbox" id="checkbox1" name="checkbox1"&gt;1.Test with accessibility checker tools&lt;/label&gt; &lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox2" class="form-control"&gt;&lt;input type="checkbox" id="checkbox2" name="checkbox2"&gt;2.Use semantic HTML&lt;/label&gt; &lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox3" class="form-control"&gt;&lt;input type="checkbox" id="checkbox3" name="checkbox3"&gt;3.Use appropriate alternative text for all images/icons&lt;/label&gt; &lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox4" class="form-control"&gt;&lt;input type="checkbox" id="checkbox4" name="checkbox4"&gt;4.Ensure keyboard navigation is possible&lt;/label&gt; &lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox5" class="form-control"&gt;&lt;input type="checkbox" id="checkbox5" name="checkbox5"&gt;5.Ensure color contrast meets accessibility standards&lt;/label&gt;&lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox6" class="form-control"&gt;&lt;input type="checkbox" id="checkbox6" name="checkbox6"&gt;6.Check for correct usage of ARIA attributes&lt;/label&gt;&lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox7" class="form-control"&gt;&lt;input type="checkbox" id="checkbox7" name="checkbox7"&gt;7.Add landmarks&lt;/label&gt;&lt;/p&gt;
&lt;p&gt;&lt;label for="checkbox8" class="form-control"&gt;&lt;input type="checkbox" id="checkbox8" name="checkbox8"&gt;8.Test with screen readers&lt;/label&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div class="section" id="the-detailed-checklist"&gt;
&lt;h2&gt;The detailed checklist&lt;/h2&gt;
&lt;div class="section" id="accessibility-checker-tools"&gt;
&lt;h3&gt;Accessibility checker tools&lt;/h3&gt;
&lt;p&gt;Testing is the most important part. Even if you are not aware of
everything in accessibility, you will know what is wrong and what you
have actually done and start to improve somewhere.&lt;/p&gt;
&lt;p&gt;You have many tools which can allow you to test your code properly and
give you some hints on the rule and/or the code possible to change.&lt;/p&gt;
&lt;p&gt;There are many ways to test a website. First we have the accessibility
tool checker. You can have it via a browser extension, via the direct
website or run it as an integrated tool in your project.&lt;/p&gt;
&lt;p&gt;Don’t forget that you can also use the developer tool with some checks
related to accessibility. For example, you can force theme colors to see
the changes. Personally, I use the browser extension &lt;a class="reference external" href="https://accessibilityinsights.io/downloads/"&gt;Accessibility
Insights&lt;/a&gt;. It suits my
needs most of the time and it’s a very complete tool.&lt;/p&gt;
&lt;p&gt;To avoid reinventing the wheel, I suggest you learn more on how to
&lt;a class="reference external" href="https://a11y.coffee/start-testing/"&gt;start accessibility testing via the article done by
a11y.coffee&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you would like to automate some tests, this is also something
possible.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“57.38% of total Issues were detected during automated tests”&lt;/em&gt;
according to &lt;a class="reference external" href="https://www.deque.com/automated-accessibility-testing-coverage/"&gt;Deque, you can find more information on the
website&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pa11y is a great tool to automate your accessibility testing, you have
the Pa11y CI which is built to run under continuous integration. You can
find &lt;a class="reference external" href="https://pa11y.org/tutorials/"&gt;many tutorials on Pa11y&lt;/a&gt; on their
website.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="html-markup"&gt;
&lt;h3&gt;HTML markup&lt;/h3&gt;
&lt;p&gt;This is something we don’t frequently think about but this does impact
the accessibility. Div and span are tags without semantic meaning and
this is really important. Semantic elements are recognized by browsers
but also by screen readers and other assistive technologies. I think I
can’t write better about how it is important than &lt;a class="reference external" href="https://accessibilitywise.info/semantic-code-why-meaning-is-important/essentials/"&gt;Semantic Code. Why
meaning is
important&lt;/a&gt;
from &lt;a class="reference external" href="http://accessibiltywise.info/"&gt;accessibiltywise.info&lt;/a&gt; from
Edward Haynes.&lt;/p&gt;
&lt;p&gt;For example, when describing an unordered list, instead of using this
code:&lt;/p&gt;
&lt;pre class="code html literal-block"&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Coffee&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tea&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Water&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;You could use these specific html elements:&lt;/p&gt;
&lt;pre class="code html literal-block"&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Coffee&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tea&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Water&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="alternative-text"&gt;
&lt;h3&gt;Alternative text&lt;/h3&gt;
&lt;p&gt;Images and icons are nice and aesthetic but it’s meaningless for people
with low or no vision.&lt;/p&gt;
&lt;p&gt;Many tools and websites integrate an alternative text to make sure
people who can’t see or have difficulties seeing the image, have at
least the description of the image. Most of the time it’s a small
description but it’s better than nothing.&lt;/p&gt;
&lt;p&gt;In the website, verify you have an attribute alt on each media,
especially images.&lt;/p&gt;
&lt;p&gt;For example, when adding the company photo in a page, you could do
something like this:&lt;/p&gt;
&lt;pre class="code html literal-block"&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt;
   &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/path/to/img&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Photo of the Company Staff holding a flag&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;To use a real use case, I took a picture from my blog below, if the image
is not accessible or the link is simply broken, it will lead to this
result as you can see below:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="image result when there is a alternative text and an image broken" src="../images/image-result-for-alternative-text.png" /&gt;
&lt;p class="caption"&gt;Image result when there is a alternative text and an image broken&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="labels"&gt;
&lt;h3&gt;Labels&lt;/h3&gt;
&lt;p&gt;Many times, people like to skip or remove labels. Design, or whatever
reason, you shouldn’t do that. Visible labels are helpful to know what
this element represents. This is really meaningful when you have a form,
for example. A real example is with the placeholder on credit card
field:&lt;/p&gt;
&lt;blockquote cite="https://twitter.com/SaraSoueidan/status/1577941158491201537"&gt;
   &lt;p&gt;Using placeholder without a label on the credit card field for
example has the screen reader say “kisses kisses kisses kisses” (cz the
placeholder is xxxx-xxxx-xxxx-xxxx) instead of “credit card number”&lt;/p&gt;
   &lt;footer&gt;—Sara Soueidan, &lt;cite&gt;Twitter&lt;/cite&gt;&lt;/footer&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a class="reference external" href="https://twitter.com/SaraSoueidan/status/1578346744550543360"&gt;The recording of the screen reader is available.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this case, best would be to add a label linked to the field with the
for attribute like this:&lt;/p&gt;
&lt;pre class="code html literal-block"&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;cardNumber&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Card Number&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
   &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;cardNumber&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;inputmode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;numeric&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;[0-9]*&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;It’s possible to add a hint if needed with a span tag. People should be
able to enter payment card numbers in whatever format is familiar to
them. This means to be able to have additional spaces, hyphens and
dashes and it’s still possible to validate the correct format of the
field.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="keyboard-navigation"&gt;
&lt;h3&gt;Keyboard Navigation&lt;/h3&gt;
&lt;p&gt;Navigating through a website can be hard if you don’t help readers,
especially when they use only a keyboard and/or a screen reader. This is
why you should use the correct HTML markup and think about the
navigation. The best way is to try to navigate like someone else will
do.&lt;/p&gt;
&lt;p&gt;You will also notice the importance of the focus indicator in this type
of navigation, to know which element you are currently focusing on. If
you have been one day removing the outline of elements with CSS without
defining a new indicator, please reconsider it after knowing this.&lt;/p&gt;
&lt;p&gt;These are the steps to navigate in a website:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Go through your page with the tab key&lt;/li&gt;
&lt;li&gt;Make sure every interactive element can be reached.&lt;/li&gt;
&lt;li&gt;Make sure every interactive element can be used.&lt;/li&gt;
&lt;li&gt;Make sure the order is logical.&lt;/li&gt;
&lt;li&gt;Make sure the focus is visible, unobscured, and has enough contrast.&lt;/li&gt;
&lt;li&gt;Do the same in reverse with Shift + Tab&lt;/li&gt;
&lt;li&gt;Make sure there are no focus traps&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The navigation is supposed to be logical through elements, if you see
something wrong then you can see how to change. This part is easier to
do when you have feedbacks or ask other folks to make sure it’s correct.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="color-and-contrast"&gt;
&lt;h3&gt;Color and contrast&lt;/h3&gt;
&lt;p&gt;Color and contrast are something which impact a lot of users:
disabilities, comfort if looking by night, low vision and so on.This is
important because this is the first thing we see in addition to the
content. Low contrast makes things hard to distinguish and hard to read,
particularly for people with low visual acuity or color blindness.&lt;/p&gt;
&lt;p&gt;You have many ways to ensure the contrast is enough and everyone can
read. You have the devtools from your browser that will help you check
directly on elements that have a color and/or background.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Color contrast with chrome devtools on djangoproject.com" src="../images/devtools-chrome-contrast.png" /&gt;
&lt;p class="caption"&gt;Color contrast of a text in the sidebar with chrome devtools on djangoproject.com&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;You can have an extension that you can add to your browser to also check
colors and contrast. For example, I personally use
&lt;a class="reference external" href="https://chrome.google.com/webstore/detail/colorblindly/floniaahmccleoclneebhhmnjgdfijgg"&gt;colorblindly&lt;/a&gt;
for Chrome to see the difference between colors visions that could
exist.&lt;/p&gt;
&lt;p&gt;Finally, you have dedicated websites or tools that will help you to
check contrast only for specific things. I really like &lt;a class="reference external" href="https://www.whocanuse.com/"&gt;whocanuse.com&lt;/a&gt;
about different types of vision between a color and the background color
associated.&lt;/p&gt;
&lt;p&gt;If you want to compare two colors with a matrix, &lt;a class="reference external" href="https://contrast-grid.eightshapes.com/"&gt;contrast-grid from
eightshapes.com&lt;/a&gt; is my go to.&lt;/p&gt;
&lt;p&gt;There are specific tools that help you to adapt the color in function of
the image for example. You can see that in social media, for example in
Instagram, the text over a background will be white or black in function
of the color, to make sure it has the correct contrast.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="aria-attributes"&gt;
&lt;h3&gt;ARIA attributes&lt;/h3&gt;
&lt;p&gt;ARIA is the abbreviation of Accessible Rich Internet Applications. This
is useful to provide accessible information in addition to the HTML
semantic, but this should be used only when it’s necessary.&lt;/p&gt;
&lt;p&gt;For example, something that should be used for showing the current
element: page, section... A good example is the breadcrumbs:&lt;/p&gt;
&lt;pre class="code html literal-block"&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt; &lt;span class="na"&gt;aria-label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;breadcrumbs&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/blog&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Blog&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;
            &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/blog/accessibility&amp;quot;&lt;/span&gt;
            &lt;span class="na"&gt;aria-current&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;page&amp;quot;&lt;/span&gt;
         &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            Accessibility
         &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;The risk with ARIA is that people think each time it’s needed to add an
attribute and it’s not the case. HTML semantics can be sufficient in
some cases. For example, a tag button doesn’t need to have a role, it
automatically has a role button. You can find more information on ARIA
roles on the &lt;a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles"&gt;MDN
website&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="landmarks"&gt;
&lt;h3&gt;Landmarks&lt;/h3&gt;
&lt;p&gt;Landmarks are the “sections” that structure the website: header, main,
footer, nav…&lt;/p&gt;
&lt;p&gt;This can be defined via the HTML tags, main have its own tag and this
allows to define the main content of the page.&lt;/p&gt;
&lt;p&gt;Landmarks are especially useful to structure the page but also to move
from a section to another easily with screen readers.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="landmarks on djangoproject.com website" src="../images/landmarks.png" /&gt;
&lt;p class="caption"&gt;Landmarks displayed with squares on djangoproject.com with Accessibility Insights*&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;One thing to not forget is for a given type of landmark is used multiple
times, for example &lt;cite&gt;&amp;lt;nav&amp;gt;&lt;/cite&gt; for the navigation landmark, then each occurrence
needs a &lt;cite&gt;aria-label&lt;/cite&gt; to tell them apart.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="screen-readers"&gt;
&lt;h3&gt;Screen readers&lt;/h3&gt;
&lt;p&gt;Screen readers are very useful for people who have disabilities or
prefer to use them to make their life easier. Many would think it’s only
for blind people but it’s not the case. Someone with dyslexia can use a
screen reader when using a computer or someone who has motricity issues,
even temporary for example. Screen reader will announce the content of a
website via text-to-speech or on a braille display. They also propose multiple
ways to interact with the website with a keyboard, it's not only reading
content: fill a form, interact with the browser and so on.&lt;/p&gt;
&lt;p&gt;There are different screen readers in function of the device or browser
supported and functionalities. JAWS and NVDA are the most popular.
VoiceOver is the one by default on Apple devices. Microsoft operating
systems use Microsoft Narrator. Android based devices provide Talkback
screen reader or VoiceView by default. For Linux and Unix systems you
have Orca or SpeakUp. You should be able to have a screen reader for
your device.&lt;/p&gt;
&lt;p&gt;You just need to try to put yourself in someone else’s shoes who can’t
perfectly see the website and walk through the website with the tool.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;To summarize, this accessibility review checklist is a good way to
introduce people to accessibility and review your own sites to correct errors
that might force people not to use your site. This one is my own
checklist but there are many nice checklists, you can give a look
at the list below.&lt;/p&gt;
&lt;p&gt;Special thanks to the reviewers of this article, who should recognize themselves.
Thank you for your support 💚&lt;/p&gt;
&lt;p&gt;-- May the future be accessible with those checklists ⭐&lt;/p&gt;
&lt;div class="section" id="other-checklists"&gt;
&lt;h4&gt;Other checklists&lt;/h4&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.magentaa11y.com/"&gt;https://www.magentaa11y.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.a11yproject.com/checklist/"&gt;https://www.a11yproject.com/checklist/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://webaim.org/standards/wcag/checklist"&gt;https://webaim.org/standards/wcag/checklist&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://webflow.com/accessibility/checklist#start"&gt;https://webflow.com/accessibility/checklist#start&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://dequeuniversity.com/checklists/web/"&gt;https://dequeuniversity.com/checklists/web/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="accessibility"/><category term="resources"/></entry><entry><title>Le FOSDEM 2024, de mon point de vue</title><link href="https://sarahabd.com/fr/blog/fosdem-2024-from-my-perspective" rel="alternate"/><published>2024-02-15T10:00:00+01:00</published><updated>2024-02-15T10:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2024-02-15:/fr/blog/fosdem-2024-from-my-perspective</id><summary type="html">&lt;p class="first last"&gt;Ma première fois au FOSDEM, mes impressions sur la conférence.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour, ça fait un moment ! Je n'ai pas eu le temps de m'occuper de mon blog ces
derniers temps, mais j'ai tellement d'idées de sujets ! Je vais commencer par la
conférence FOSDEM 🙂&lt;/p&gt;
&lt;p&gt;C'était ma première fois à cette conférence. Le FOSDEM est une conférence de 2 jours
sur les logiciels libres et open source. La conférence est aussi gratuite et organisée par
des bénévoles, comme l'open source. Elle a lieu à Bruxelles, en Belgique,
cette année. Vous pouvez en savoir plus sur le
&lt;a class="reference external" href="https://fosdem.org/2024/"&gt;site du FOSDEM&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;J'y suis allée avec l'équipe accessibilité de Django et avec quelques
amis de l'équipe Wagtail. C'est toujours plus sympa de faire une
conférence entre amis !&lt;/p&gt;
&lt;p&gt;Personnellement, j'ai aimé la conférence, même s'il y a peut-être aussi l'effet
de la première fois. Par rapport aux autres conférences où je suis
allée, il y a beaucoup de tracks (aussi appelées devrooms), donc ça peut être difficile de s'y retrouver
au début, mais on finit par trouver son chemin (ou par suivre des
personnes qui vont au même talk).&lt;/p&gt;
&lt;p&gt;J'ai vu quelques talks sur l'accessibilité et d'autres que je voulais voir par
curiosité. J'ai aussi soutenu mon ami &lt;a class="reference external" href="https://fosdem.org/2024/schedule/speaker/DVT93T/"&gt;Sage Abdullah&lt;/a&gt;, qui donnait lui aussi
un talk ❤️&lt;/p&gt;
&lt;p&gt;Les talks auxquels j'ai assisté :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-2522-outreachy-1000-interns/"&gt;Keynote, Outreachy, 1000 interns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-3317-web-accessibility-and-environmental-sustainability-and-with-popular-cms/"&gt;Web Accessibility and Environmental Sustainability and with Popular
CMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-3326-web-accessibility-for-open-source-privacy-security-tools/"&gt;Web-accessibility for open-source privacy &amp;amp; security tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-2723-power-profiling-my-entire-house-with-the-firefox-profiler/"&gt;Power profiling my entire house with the Firefox Profiler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-2716-firefox-power-profiling-a-powerful-visualization-of-web-sustainability/"&gt;Firefox power profiling: a powerful visualization of web
sustainability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-2749-modern-editing-experiences-you-can-build-in-your-cms/"&gt;Modern editing experiences you can build in your CMS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C'était aussi assez drôle : j'ai surtout fait des conférences entièrement en anglais,
et comme je suis française, je ne savais jamais si je devais parler français
ou anglais. Parfois, je découvrais après avoir parlé en anglais à
quelqu'un que cette personne parlait en fait français avec quelqu'un d'autre,
hahaha.&lt;/p&gt;
&lt;p&gt;Les talks que je voulais voir étaient surtout le dimanche, donc j'ai beaucoup parlé avec
des gens le samedi et découvert les différents stands. C'était
vraiment varié : Mastodon, Mozilla, PostgreSQL, Open Design Collective,
OpenSSL, Debian, et même XMPP !&lt;/p&gt;
&lt;p&gt;Je me suis fait de nouveaux amis, bien sûr, j'ai revu d'anciens amis, et j'ai rencontré des personnes dont je
connaissais le nom sans jamais les avoir vues en vrai, donc c'était plutôt sympa.&lt;/p&gt;
&lt;p&gt;Ce que j'ai vraiment aimé, ce sont les BoF, pour Birds of a Feather. Ça
a lieu la plupart du temps après un talk précis, et c'est une bonne
occasion de discuter avec les personnes présentes à un talk ou simplement avec celles impliquées
dans une track spécifique (par exemple Python ou l'accessibilité).&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;BoF - &lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-3700-outreachy-connect-newcomers-old-friends/"&gt;Outreachy Connect: Newcomers &amp;amp; Old friends&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;BoF - &lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-3757-web-accessibility-and-atag/"&gt;Web Accessibility and ATAG&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je suis allée à celui d'Outreachy et à un autre sur l'accessibilité. C'était
vraiment intéressant de parler avec des gens, de poser des questions et de découvrir des
ressources grâce aux autres. J'aimerais beaucoup voir aboutir la ressource
sur les WCAG pour les développeurs et développeuses backend dont nous avons parlé pendant le
BoF accessibilité, et avoir une track dédiée à l'accessibilité.&lt;/p&gt;
&lt;p&gt;En tant que membre du conseil d'administration de la DSF, le programme Outreachy me semble intéressant
pour Django à un moment donné. J'ai aussi trouvé déroutant de voir autant de
personnes ne pas connaître Django du tout, je pense que ce serait bien d'avoir
quelque chose qui représente Django l'année prochaine. Cela dit, nous avons trouvé des personnes qui utilisent
Django ou qui le connaissent, et elles ont trouvé génial de voir toute l'équipe accessibilité
à l'événement. On nous a remerciés pour notre travail sur l'accessibilité : c'est
inestimable d'avoir des retours là-dessus et nous adorons ça.&lt;/p&gt;
&lt;p&gt;Sage a représenté les CMS en Python avec son talk, et beaucoup de personnes dans la
salle ne faisaient que du PHP, donc c'était agréable de voir d'autres
personnes apprécier le travail fait dans un autre langage pour à peu près le même objectif :
les systèmes de gestion de contenu.&lt;/p&gt;
&lt;p&gt;Malheureusement, je n'ai pas eu le temps de voir &lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-2311-making-python-safer-than-ever/"&gt;le talk de Cheuk&lt;/a&gt; ni les talks de la devroom Python,
mais je suis contente de l'avoir au moins croisée.&lt;/p&gt;
&lt;p&gt;Certaines salles étaient complètement pleines, surtout pour les talks de
Daniel Stenberg ou de Scott Chacon, mais j'ai pris plaisir à les regarder en ligne :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.youtube.com/watch?v=aolI_Rz0ZqY"&gt;So you think you know Git&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-1931-you-too-could-have-made-curl-/"&gt;You too could have made curl!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je compte y retourner l'année prochaine, et j'espère vous y voir ou avoir
votre soutien, où que vous soyez !&lt;/p&gt;
</content><category term="blog"/><category term="reflexion"/><category term="open-source"/></entry><entry><title>FOSDEM 2024, from my perspective</title><link href="https://sarahabd.com/blog/fosdem-2024-from-my-perspective" rel="alternate"/><published>2024-02-15T10:00:00+01:00</published><updated>2024-02-15T10:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2024-02-15:/blog/fosdem-2024-from-my-perspective</id><summary type="html">&lt;p class="first last"&gt;First time for me to got to FOSDEM, my thoughts of the conference.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi there, it’s been a while! I hadn’t time to take care of my blog these
days but I have so many ideas to write about! I will start with the
FOSDEM conference 🙂&lt;/p&gt;
&lt;p&gt;It’s my first time to this conference, FOSDEM is a 2 days conference
about free open source software, the conference is also free, run by
volunteers, same as open source. It takes place in Brussels, Belgium
this year. You can learn more on the
&lt;a class="reference external" href="https://fosdem.org/2024/"&gt;FOSDEM website&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I have been there with the Django Accessibility Team and with some
friends from the Wagtail team. It’s always more fun when you do a
conference with friends!&lt;/p&gt;
&lt;p&gt;Personally, I liked the conference, I guess there might be also the hype
of the first time conference here. Compared to other conference I have
been, you have many tracks (also called Devroom) so it can be hard to find
your way at the beginning but you finally manage your way (or follow some
people who are going to the same talk).&lt;/p&gt;
&lt;p&gt;I have seen few accessibility talks and some I wanted to see out of
curiosity. I also support my friend &lt;a class="reference external" href="https://fosdem.org/2024/schedule/speaker/DVT93T/"&gt;Sage Abdullah&lt;/a&gt; who was giving a talk
too ❤️&lt;/p&gt;
&lt;p&gt;The talks I have been to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-2522-outreachy-1000-interns/"&gt;Keynote, Outreachy, 1000 interns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-3317-web-accessibility-and-environmental-sustainability-and-with-popular-cms/"&gt;Web Accessibility and Environmental Sustainability and with Popular
CMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-3326-web-accessibility-for-open-source-privacy-security-tools/"&gt;Web-accessibility for open-source privacy &amp;amp; security tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-2723-power-profiling-my-entire-house-with-the-firefox-profiler/"&gt;Power profiling my entire house with the Firefox Profiler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-2716-firefox-power-profiling-a-powerful-visualization-of-web-sustainability/"&gt;Firefox power profiling: a powerful visualization of web
sustainability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-2749-modern-editing-experiences-you-can-build-in-your-cms/"&gt;Modern editing experiences you can build in your CMS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It’s also quite funny, I have done mostly conferences in full english
and since I’m french, I wasn’t sure each time if I should speak french
or english, and sometimes I discovered after talking in english to
someone, this person was actually speaking french to someone else
hahaha.&lt;/p&gt;
&lt;p&gt;The talks I wanted to see was mostly on Sunday so I talked a lot to
people in Saturday and discovering the various stands there were. It was
really diverse, Mastodon, Mozilla, Postgresql, Open design collective,
OpenSSL, Debian, even XMPP!&lt;/p&gt;
&lt;p&gt;I made new friends, of course, see old friends, and see some people I
know their name but never see them in real so it’s quite nice.&lt;/p&gt;
&lt;p&gt;The thing I really like was the BoF, which mean Both of Feather, it
happens most of the time after a specific talk, and it’s a good
opportunity to discuss with people from a talk or just people involved
in a specific track (for example python or accessibility).&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;BoF - &lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-3700-outreachy-connect-newcomers-old-friends/"&gt;Outreachy Connect: Newcomers &amp;amp; Old friends&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;BoF - &lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-3757-web-accessibility-and-atag/"&gt;Web Accessibility and ATAG&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have been to the Outreachy one and another one on accessibility. It
was really interesting to talk with people, ask questions and learn some
resources from other people. I would love to see happening the resource
about the WCAG for backend developers we were talking about in
accessibility BoF and have a dedicated track for accessibility.&lt;/p&gt;
&lt;p&gt;As the DSF board member, the Outreachy program seems to be interesting to
have for Django at some point. I also find disturbing to see so many
people no knowing Django at all, I think it would be nice to have
something representing Django next year. Nevertheless, we did find some people using
Django or knowing Django and found amazing to see the full accessibility
team at the event. We were thanks for our work on accessibility, this is
so priceless to have feedback on that and we love that.&lt;/p&gt;
&lt;p&gt;Sage represent CMS with python with his talk, and a lot of people in the
room was only doing PHP, so it was nice to see the appreciation of other
people of the work done in another language for quite same purpose in
content management system.&lt;/p&gt;
&lt;p&gt;Unfortunately, I didn't have time to see &lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-2311-making-python-safer-than-ever/"&gt;Cheuk's talk&lt;/a&gt; or talk from the Python Devroom
but I'm glad I saw her at least.&lt;/p&gt;
&lt;p&gt;Some of them were totally full, especially when it's a talk given by
Daniel Stenberg or Scott Chacon but I enjoyed watch them online:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.youtube.com/watch?v=aolI_Rz0ZqY"&gt;So you think you know Git&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://fosdem.org/2024/schedule/event/fosdem-2024-1931-you-too-could-have-made-curl-/"&gt;You too could have made curl!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I plan to be there next year, and I hope to see you there or have
your support from wherever you are!&lt;/p&gt;
</content><category term="blog"/><category term="reflexion"/><category term="open-source"/></entry><entry><title>2023, le bilan de l'année</title><link href="https://sarahabd.com/fr/blog/2023-year-in-review" rel="alternate"/><published>2024-01-04T10:00:00+01:00</published><updated>2024-01-04T10:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2024-01-04:/fr/blog/2023-year-in-review</id><summary type="html">&lt;p class="first last"&gt;Bonjour, ça fait un moment... Tout d'abord, je vous souhaite une bonne année, meilleurs vœux !!&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour, ça fait un moment... Tout d'abord, je vous souhaite une bonne année, meilleurs vœux !!&lt;/p&gt;
&lt;p&gt;J'ai pris le temps de faire un bilan de l'année sur le même modèle que celui de 2021.
J'ai été malade en fin d'année, donc je n'ai pas terminé mon article avant la fin de 2023, mais
il est enfin prêt à être publié aujourd'hui ! 🎉&lt;/p&gt;
&lt;div class="section" id="avertissement"&gt;
&lt;h2&gt;Avertissement&lt;/h2&gt;
&lt;p&gt;Je n'ai fait relire cet article par personne et l'anglais n'est pas ma langue maternelle (la version originale est en anglais). S'il y a des erreurs, n'hésitez pas à me contacter et je corrigerai l'article.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="tl-dr"&gt;
&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;Cette année a été incroyable, j'ai réussi à faire des choses que je n'aurais jamais imaginé faire. Je suis très reconnaissante pour tout le soutien que j'ai reçu cette année, pour tous les nouveaux amis incroyables que je me suis faits et pour toutes les opportunités que j'ai eues.&lt;/p&gt;
&lt;p&gt;Mes temps forts de l'année :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Aider à organiser la DjangoCon Europe&lt;/li&gt;
&lt;li&gt;Tout ce qui concerne le programme Djangonaut Space&lt;/li&gt;
&lt;li&gt;Donner mon premier talk&lt;/li&gt;
&lt;li&gt;Changer de travail&lt;/li&gt;
&lt;li&gt;Me faire des amis partout dans le monde&lt;/li&gt;
&lt;li&gt;Être élue au conseil d'administration de la DSF&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="apprentissages-et-progres"&gt;
&lt;h2&gt;Apprentissages et progrès&lt;/h2&gt;
&lt;p&gt;J'ai beaucoup appris cette année, en essayant des choses, surtout des choses qui me faisaient vraiment peur, et en faisant des erreurs, bien sûr.
Je pense que cette année a été une année de changement pour moi.&lt;/p&gt;
&lt;p&gt;J'ai essayé de me rapprocher de ce que je veux vraiment. J'ai changé de travail pour un poste où j'utilise la technologie
que je préfère, avec un impact sur le changement climatique.&lt;/p&gt;
&lt;p&gt;J'ai aussi appris en discutant avec des amis. Je ne suis toujours pas complètement fière de mon niveau d'anglais, même si beaucoup de gens me disent
qu'il est très bien, mais je suppose que c'est juste une question d'aisance pour trouver les mots justes pour dire ce que je veux.&lt;/p&gt;
&lt;p&gt;J'ai aussi rencontré beaucoup de gens, et je suis reconnaissante qu'ils soient tous gentils et adorables, grâce à l'incroyable communauté Django 💚
Je suis très fière de l'équipe de Djangonaut Space : nous avons accompli quelque chose de vraiment chouette et nous avons construit une belle relation ensemble.
J'ai réalisé grâce à ça que je suis vraiment douée pour mettre les gens en relation.&lt;/p&gt;
&lt;p&gt;J'espère pouvoir continuer à grandir, progresser, accueillir des gens dans la communauté Django et rencontrer d'autres amis du monde
entier.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conferences"&gt;
&lt;h2&gt;Conférences&lt;/h2&gt;
&lt;p&gt;J'ai organisé la DjangoCon Europe cette année, c'était une super expérience pour moi. &lt;a class="reference external" href="/fr/blog/djangocon-europe-2023-from-attendee-to-organizer"&gt;J'ai écrit à ce sujet&lt;/a&gt;, et j'ai vraiment hâte d'être à la
prochaine édition à Vigo ! Je pense que cette fois, j'y participerai simplement, pour pouvoir voir davantage mes amis et échanger avec les gens,
surtout maintenant que je fais partie du conseil d'administration de la DSF : recueillir des retours et construire l'avenir.&lt;/p&gt;
&lt;p&gt;J'ai aussi assisté à la DjangoCon US, c'était très bien, mais je n'y suis pas restée longtemps à cause du décalage horaire. J'espère pouvoir y assister en 2024,
j'ai peut-être une chance d'y aller 🤞🏽&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="djangonaut-space"&gt;
&lt;h2&gt;Djangonaut Space&lt;/h2&gt;
&lt;p&gt;Si quelqu'un m'avait dit que je cocréerais ce projet et que
&lt;a class="reference external" href="https://www.djangoproject.com/weblog/2023/dec/08/2023-malcolm-tredinnick-memorial-prize-awarded-to/"&gt;nous recevrions le prix Malcolm Tredinnick&lt;/a&gt;
pour ça, je ne l'aurais pas cru, hahaha.&lt;/p&gt;
&lt;p&gt;Je suis vraiment heureuse de ce que nous avons accompli et de l'équipe que nous avons formée. Aujourd'hui, je les considère tous comme mes amis, et ce qui
est incroyable, c'est que quand nous nous sommes vus en vrai, c'était comme si nous étions amis depuis des années, alors que c'était la première
fois que nous nous voyions ailleurs que devant un ordinateur.&lt;/p&gt;
&lt;p&gt;Nous faisons vraiment de notre mieux pour faire de &lt;a class="reference external" href="https://djangonaut.space/"&gt;Djangonaut Space&lt;/a&gt; un beau projet. J'espère que ce projet aidera beaucoup de Djangonautes à
contribuer et à faire décoller leurs contributions 🚀&lt;/p&gt;
&lt;p&gt;Ce qui est drôle, c'est que parfois je me dis que je devrais suivre notre programme moi-même, hahaha. J'aimerais vraiment améliorer mes compétences
en 2024.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="carriere-professionnelle"&gt;
&lt;h2&gt;Carrière professionnelle&lt;/h2&gt;
&lt;p&gt;En parlant d'améliorer mes compétences, j'ai changé de travail pour me challenger et ne pas rester dans ma zone de confort.
Ce n'est clairement pas facile, et j'ai un syndrome de l'imposteur dont il est difficile de se débarrasser, mais je continue d'avancer, d'essayer de progresser et de ne pas être trop dure avec moi-même.&lt;/p&gt;
&lt;p&gt;Malgré ça, je suis contente d'avoir changé de travail, j'ai découvert beaucoup de choses et j'apprends encore. J'ai aussi appris sur moi-même
avec ces expériences : par exemple, je pense que je suis douée pour aider à faire avancer les choses.&lt;/p&gt;
&lt;p&gt;Je suis aussi très reconnaissante pour tout le travail open source et les opportunités qu'on m'a offertes. Je sais que ça a un impact
sur la communauté, mais aussi sur ma carrière. Il y a ce sentiment que certaines personnes ont de ne pas en faire assez - oui, je sais,
ça peut paraître bizarre venant de quelqu'un qui fait déjà beaucoup de choses - et de vouloir en faire plus, mais j'essaie de garder un bon équilibre
entre bénévolat et repos. Si vous ressentez la même chose, n'oubliez pas que le temps pour soi est important aussi.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="talks-et-benevolat"&gt;
&lt;h2&gt;Talks et bénévolat&lt;/h2&gt;
&lt;p&gt;Je pense que c'est ma meilleure année en matière de bénévolat. J'ai été bénévole pour 2 DjangoCons, j'aide à l'organisation de Djangonaut Space,
je contribue au code de Django et à son accessibilité et je les maintiens, et j'organise le meetup Django Paris. Je n'aurais jamais imaginé faire
tout ça en début d'année, mais je crois que j'ai un fort appétit pour faire les choses quand personne d'autre ne veut les faire
- suis-je bizarre ?&lt;/p&gt;
&lt;p&gt;En tout cas, je suis vraiment fière d'avoir contribué à tout ce travail, le résultat est super et j'ai beaucoup appris grâce à
ces expériences. Je me suis fait de nouveaux amis et j'ai eu plaisir à retrouver d'anciens amis. Je ferai de mon mieux pour continuer à travailler sur tous ces sujets.&lt;/p&gt;
&lt;p&gt;De plus, j'ai donné un &lt;a class="reference external" href="https://youtu.be/15ITa9E2dEs?si=57piJJ5PY8Es7MIO"&gt;talk à la PyLadiesCon sur la création d'un programme de mentorat&lt;/a&gt;. Si vous me connaissez, vous savez déjà que
je ne suis vraiment pas à l'aise pour parler en public, encore moins en anglais. Un ami plein de sagesse m'a dit qu'il faut pratiquer pour
être plus à l'aise - merci Tim Schilling. Alors j'essaie, même si je trouve toujours ça effrayant, hahaha. Si vous pensez
le faire un jour, essayez. Vous découvrirez peut-être que vous êtes un·e orateur·rice incroyable 😄&lt;/p&gt;
&lt;p&gt;Comme je le disais, j'ai essayé beaucoup de choses cette année, y compris me présenter au conseil d'administration de la DSF. Pour être honnête, ce n'était vraiment pas
prévu. Beaucoup d'amis m'ont aidée à l'envisager et à comprendre pourquoi je devrais le faire. Merci si vous m'avez aidée dans
ma décision et/ou si vous avez voté lors de cette élection. Il y avait des candidat·es incroyables et je suis très honorée d'être
l'une des représentantes de la DSF au conseil d'administration. Je découvre encore comment ça fonctionne et comment aider correctement.
Je pense écrire des articles à ce sujet à un moment donné pour les partager avec vous.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="amis-et-soutien"&gt;
&lt;h2&gt;Amis et soutien&lt;/h2&gt;
&lt;p&gt;J'ai rencontré tellement de gens cette année, je suis vraiment reconnaissante d'avoir eu l'occasion d'en voir certains en vrai
lors de conférences ou de meetups. Ce que j'aime le plus dans la communauté tech, c'est que les amitiés virtuelles sont de vraies
amitiés. J'ai la chance d'avoir des amis partout dans le monde grâce à mes expériences. Certains m'ont soutenue,
et j'en ai soutenu d'autres. On s'amuse virtuellement ou en vrai, quelque part.
C'est vraiment agréable et j'adore la communauté pour ça.
Merci si vous avez contribué à mes réussites ou si vous m'avez soutenue dans mes échecs,
j'espère avoir retenu toutes les leçons pour faire mieux en 2024.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="note-a-moi-meme"&gt;
&lt;h2&gt;Note à moi-même&lt;/h2&gt;
&lt;p&gt;En 2023, j'ai essayé des choses que je ne pensais pas faire un jour. J'ai beaucoup d'objectifs en tête et une grande liste de choses à faire pour 2024, mais je suis confiante.
Je suis sûre que je ne pourrai pas tout faire, mais c'est noté quelque part pour avancer.
Je pense que cette nouvelle année sera une bonne année, et je vous souhaite le meilleur si vous lisez encore ceci.&lt;/p&gt;
&lt;p&gt;Quelques conseils pour cette nouvelle année :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Rester organisée&lt;/li&gt;
&lt;li&gt;Continuer d'essayer, faire des erreurs, ce n'est pas si grave&lt;/li&gt;
&lt;li&gt;La pratique est importante pour devenir bon·ne dans quelque chose&lt;/li&gt;
&lt;li&gt;Quelque chose que vous trouvez bête peut être utile à quelqu'un d'autre&lt;/li&gt;
&lt;li&gt;Ne pas avoir peur de demander&lt;/li&gt;
&lt;li&gt;Garder ses objectifs en tête, et tout le reste aussi&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="reflexion"/></entry><entry><title>2023, year in review</title><link href="https://sarahabd.com/blog/2023-year-in-review" rel="alternate"/><published>2024-01-04T10:00:00+01:00</published><updated>2024-01-04T10:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2024-01-04:/blog/2023-year-in-review</id><summary type="html">&lt;p class="first last"&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;
</summary><content type="html">&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;I took the time to do a review of the year with the same model as I've done in 2021.
I was sick for the end of the year so I didn't finish my article before the end of 2023 but,
it's finished to be published today! 🎉&lt;/p&gt;
&lt;div class="section" id="disclaimer"&gt;
&lt;h2&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;I didn't review my article by someone else and I'm not a native English speaker, if there are mistakes, feel free to contact me and I will edit the article.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="tl-dr"&gt;
&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;This year was incredible, I success to do things I can’t imagine do. I am very thankful for all the support I had this year, all the new amazing friends I have, all the opportunities I had.&lt;/p&gt;
&lt;p&gt;My highlights for the year have been:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Helps organizing the DjangoCon Europe&lt;/li&gt;
&lt;li&gt;All about Djangonaut Space program&lt;/li&gt;
&lt;li&gt;Do my first talk&lt;/li&gt;
&lt;li&gt;Change job&lt;/li&gt;
&lt;li&gt;Make friends all over the world&lt;/li&gt;
&lt;li&gt;Be elected for the DSF Board&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="learning-and-improvements"&gt;
&lt;h2&gt;Learning and improvements&lt;/h2&gt;
&lt;p&gt;I've learned a lot this year, by trying things, especially things I was really afraid of, and making mistakes of course.
I think this year was a year of change for me.&lt;/p&gt;
&lt;p&gt;I tried to be more close to what I really want. I changed job to a job where I do the technology
I like the most with an impact on climate change.&lt;/p&gt;
&lt;p&gt;I also learned by chatting with friends. I'm still not completely proud of my English level despite many people would say
it's really fine but I guess it’s just a matter of being comfortable to say the correct words for the meaning I want.&lt;/p&gt;
&lt;p&gt;I also met many people, I’m thankful they are all kind and lovely, thanks to the amazing Django community 💚
I’m very proud of the team of Djangonaut Space, we achieve something really nice and we have built a great relationship together.
I realized by that I’m really good at connecting people to each other.&lt;/p&gt;
&lt;p&gt;I hope to be able to continue to grow, improve and welcome people to the Django community and met other friends from all over
the world.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conferences"&gt;
&lt;h2&gt;Conferences&lt;/h2&gt;
&lt;p&gt;I've organized the DjangoCon Europe this year, it was a great experience for me. &lt;a class="reference external" href="/blog/djangocon-europe-2023-from-attendee-to-organizer"&gt;I wrote on this&lt;/a&gt;, and I’m really excited to the
next edition in Vigo! I think this time I will only attend to be able to see more my friends and exchange with people,
especially as I’m part of the DSF board, get feedback and build the future.&lt;/p&gt;
&lt;p&gt;I've also attended to DjangoCon US, it was very nice but I didn’t attend so long due to timezone. I hope to be able to attend in 2024,
I might have a chance to come 🤞🏽&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="djangonaut-space"&gt;
&lt;h2&gt;Djangonaut Space&lt;/h2&gt;
&lt;p&gt;If someone would have told me that I would co-create this project and
&lt;a class="reference external" href="https://www.djangoproject.com/weblog/2023/dec/08/2023-malcolm-tredinnick-memorial-prize-awarded-to/"&gt;we will get the Malcolm Tredinnick Award&lt;/a&gt;
for that I wouldn't trust this person hahaha.&lt;/p&gt;
&lt;p&gt;I'm really happy for we have achieved and the team we create. Now, I consider all of them as my friends and the thing which
is amazing is when we saw each other in real life, it's like we know us like we are friends since years but this is the first
time we are seeing each other not in front of the computer.&lt;/p&gt;
&lt;p&gt;We are really trying our best to make &lt;a class="reference external" href="https://djangonaut.space/"&gt;Djangonaut Space&lt;/a&gt; a good project. I hope this project will help a lot of Djangonauts to
contribute and skyrocket their contributions 🚀&lt;/p&gt;
&lt;p&gt;The funny thing is sometimes I think I should follow our program for myself hahaha. I really would like to improve my skills
in 2024.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="professional-career"&gt;
&lt;h2&gt;Professional career&lt;/h2&gt;
&lt;p&gt;Talking about improving my skills, I changed job to challenge myself and not staying in my comfort zone.
This is clearly not easy and I have the impostor syndrome that's hard to get rid of, but I keep going and trying to improve  and be not too hard with myself.&lt;/p&gt;
&lt;p&gt;Despite that, I’m happy I have changed job, I have discovered a lot and still learning. I have also learned about myself
with those experiences, for example, I think I’m good at help push something forward.&lt;/p&gt;
&lt;p&gt;I’m also really thankful of all the open source work and opportunities I have been given. I know that this has an impact
in the community but also in my career. There is the feeling like some people have, not doing enough - yeah I know,
this can be weird as someone who already doing a lot of things - and want to do more but I’m trying to keep a good balance
with volunteering and rest. If you have the same feeling, don't forget that, time for yourself is important too.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="talk-and-volunteering"&gt;
&lt;h2&gt;Talk and volunteering&lt;/h2&gt;
&lt;p&gt;I guess this is my best year for volunteering. I've volunteered for 2 DjangoCons, I help on Djangonaut Space organization,
contribute and maintain Django code and accessibility, and organize Django Paris meetup. I wouldn't have imagined doing
all this at the start of the year, but I think I have a strong appetite for doing things when nobody else wants to do them
- am I weird?&lt;/p&gt;
&lt;p&gt;Anyway, I’m really proud to have contribute to all of this work, the result is great and I’ve learned a lot with
these experiences. I made new friends and enjoyed seeing old friends. I'll do my best to keep working on all these issues.&lt;/p&gt;
&lt;p&gt;Moreover, I have given a &lt;a class="reference external" href="https://youtu.be/15ITa9E2dEs?si=57piJJ5PY8Es7MIO"&gt;talk for PyLadiesCon about how to create a mentorship program&lt;/a&gt;. If you know me, you already know that
I’m really not confident talking in public, even less if it’s in English. A wise friend told me you have to practice to
be more comfortable - Thank you Tim Schilling. So I’m trying even if I still find that scary hahaha. If you are thinking
to do that one day, just try. Maybe you will discover you are an amazing speaker 😄&lt;/p&gt;
&lt;p&gt;As I was saying before, I've tried many things this year, including run for the DSF board. This is something I really didn't
planned to do to be honest. Many friends have helped me to consider it and why I should do it. Thank you if you helped me in
my decision and/or if you have voted for this election. There were amazing candidates and I'm very honored to be
one of the DSF's representative on the board of directors. I'm still figuring out how it works and how to help correctly.
I'm thinking of doing blog posts on this at some point to share with you.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="friends-and-support"&gt;
&lt;h2&gt;Friends and support&lt;/h2&gt;
&lt;p&gt;I have met so many people this year, I'm really thankful to had the opportunities to see some of them in real life
during conferences or meetups. The thing I like the most in tech community is the friends that you have virtually are real
friendships. I have the chance to have friends all over the world with my experiences. I had support from some of them,
I also gave support to others. Have fun virtually or in real life in some place.
This is really nice and I love the community for that.
Thank you if you have contribute to my success or support me in my failure,
I hope to have learned all the lesson to do better in 2024.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="reminder-to-myself"&gt;
&lt;h2&gt;Reminder to myself&lt;/h2&gt;
&lt;p&gt;2023 I tried things I didn’t think I would have done. I have many goals in mind and big to-do list for 2024 but I'm confident,
I'm sure I will not able to do everything but it's listed somewhere to make progress in it.
I think this new year will be a good one and I hope the best for you if you are still reading this.&lt;/p&gt;
&lt;p&gt;Piece of advice to tell for this new year:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Keep being organized&lt;/li&gt;
&lt;li&gt;Keep trying, making mistakes is not that bad&lt;/li&gt;
&lt;li&gt;Practice is important to be good at something&lt;/li&gt;
&lt;li&gt;Something that you might think it’s stupid might be helpful for someone else&lt;/li&gt;
&lt;li&gt;Don’t be afraid to ask&lt;/li&gt;
&lt;li&gt;Keep your goals in mind and the rest too&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="reflexion"/></entry><entry><title>TIL : les contraintes Django</title><link href="https://sarahabd.com/fr/til/django-constraints" rel="alternate"/><published>2023-08-12T10:00:00+02:00</published><updated>2023-08-12T10:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2023-08-12:/fr/til/django-constraints</id><summary type="html">&lt;p class="first last"&gt;J'ai récemment travaillé sur des contraintes et je voulais écrire quelque chose dessus, pour m'en souvenir.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour,&lt;/p&gt;
&lt;p&gt;J'ai récemment travaillé sur des contraintes et je voulais écrire
quelque chose dessus, pour m'en souvenir. J'espère que ça vous sera utile aussi.&lt;/p&gt;
&lt;p&gt;Les contraintes de base de données sont vraiment utiles pour s'assurer que chaque ligne est valide
avant de l'enregistrer. Il existe deux types de contraintes que l'on peut utiliser
avant d'enregistrer une nouvelle ligne dans une table avec Django : &lt;tt class="docutils literal"&gt;CheckConstraint&lt;/tt&gt;
et &lt;tt class="docutils literal"&gt;UniqueConstraint&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;J'utilise PostgreSQL, qui dispose d'outils puissants : on peut définir des contraintes
de base de données en fonction de ce qui est implémenté par Django.&lt;/p&gt;
&lt;p&gt;Les explications sont toujours meilleures avec un exemple, alors voici une contrainte
pour éviter le chevauchement entre la date de début et la date de fin :&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;start_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;end_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;   &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;constraints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;         &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CheckConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;               &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Q&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start_at__lt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;end_at&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;               &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'start_at_before_end_at'&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="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UniqueConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;               &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'start_date'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'end_date'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;               &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'unique_event_dates'&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;/pre&gt;
&lt;p&gt;La &lt;tt class="docutils literal"&gt;CheckConstraint&lt;/tt&gt; garantit que &lt;tt class="docutils literal"&gt;start_at&lt;/tt&gt; est antérieur à
&lt;tt class="docutils literal"&gt;end_at&lt;/tt&gt;. La &lt;tt class="docutils literal"&gt;UniqueConstraint&lt;/tt&gt; garantit qu'il n'y a pas deux
événements avec la même &lt;tt class="docutils literal"&gt;start_date&lt;/tt&gt; et la même &lt;tt class="docutils literal"&gt;end_date&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;J'ai découvert que lorsqu'on crée une &lt;tt class="docutils literal"&gt;UniqueConstraint&lt;/tt&gt; dans Django,
les valeurs &lt;tt class="docutils literal"&gt;NULL&lt;/tt&gt; sont considérées comme distinctes, ce que je ne voulais pas dans mon
cas.&lt;/p&gt;
&lt;p&gt;Pour reprendre mon exemple précédent, voici 2 enregistrements :&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="9%" /&gt;
&lt;col width="45%" /&gt;
&lt;col width="45%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head"&gt;id&lt;/th&gt;
&lt;th class="head"&gt;start_date&lt;/th&gt;
&lt;th class="head"&gt;end_date&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;2019-12-31&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;2019-12-31&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Les deux ont la même &lt;tt class="docutils literal"&gt;end_date&lt;/tt&gt; et une &lt;tt class="docutils literal"&gt;start_date&lt;/tt&gt; à &lt;tt class="docutils literal"&gt;NULL&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Ces deux enregistrements seront considérés comme uniques, car en SQL un NULL n'est pas égal
à un autre &lt;tt class="docutils literal"&gt;NULL&lt;/tt&gt; : les deux enregistrements sont donc considérés comme distincts.&lt;/p&gt;
&lt;p&gt;On peut utiliser &lt;tt class="docutils literal"&gt;WITH DISTINCT NULL VALUES&lt;/tt&gt; avec PostgreSQL 15, mais dans mon
cas j'utilisais une version plus ancienne, évidemment, donc j'ai dû utiliser
une autre solution.&lt;/p&gt;
&lt;p&gt;Si vous voulez vous assurer que les valeurs &lt;tt class="docutils literal"&gt;NULL&lt;/tt&gt; ne sont pas considérées comme
distinctes dans la &lt;tt class="docutils literal"&gt;UniqueConstraint&lt;/tt&gt;, vous pouvez utiliser à la place une fonction de hachage avec
l'attribut unique=True.&lt;/p&gt;
&lt;p&gt;Voici un exemple de fonction de hachage avec une valeur unique, basé sur
le code précédent avec la classe Event. Un champ &lt;tt class="docutils literal"&gt;sha256_hash&lt;/tt&gt; qui
combine dans un hash tous les champs que je veux :&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;hashlib&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;json&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;start_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;end_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;fancy_field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;sha256_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BinaryField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&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="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;__save__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__save__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sha256_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compute_sha256_hash&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;   &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;compute_sha256_hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;json_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;         &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;         &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;               &lt;span class="s2"&gt;&amp;quot;start_at&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;               &lt;span class="s2"&gt;&amp;quot;end_at&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;               &lt;span class="s2"&gt;&amp;quot;fancy_field&amp;quot;&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="c1"&gt;# Forces datetime to use timestamp due to inconsistency&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="c1"&gt;# in timezone format.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;json_object&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;start_at&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_at&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;json_object&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;end_at&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end_at&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;      &lt;span class="n"&gt;json_repr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;         &lt;span class="n"&gt;json_object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;         &lt;span class="n"&gt;sort_keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;         &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;         &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DjangoJSONEncoder&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json_repr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Le &lt;tt class="docutils literal"&gt;sha256_hash&lt;/tt&gt; est unique et ne devrait pas accepter de valeurs nulles, mais avec
les attributs &lt;tt class="docutils literal"&gt;blank=True&lt;/tt&gt; et &lt;tt class="docutils literal"&gt;null=True&lt;/tt&gt;, il peut en avoir.
Il faut alors remplir les valeurs existantes s'il y en a.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Et s'il y a déjà des données dans la table ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Le &lt;tt class="docutils literal"&gt;sha256_hash&lt;/tt&gt; est unique et ne devrait pas accepter de valeurs nulles, mais avec
les attributs &lt;tt class="docutils literal"&gt;blank=True&lt;/tt&gt; et &lt;tt class="docutils literal"&gt;null=True&lt;/tt&gt;, il peut en avoir.
Il faut alors remplir les valeurs existantes s'il y en a.&lt;/p&gt;
&lt;p&gt;Pour cela, on modifie l'attribut pour autoriser les valeurs nulles :&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;start_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;end_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;fancy_field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;sha256_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BinaryField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&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="err"&gt;…&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Ensuite, on peut remplir la valeur avec une commande Django en
filtrant la table Event existante sur les lignes où le champ &lt;tt class="docutils literal"&gt;sha256_hash&lt;/tt&gt; est
nul, et en appelant la méthode &lt;tt class="docutils literal"&gt;compute_sha256_hash&lt;/tt&gt; de la classe pour
créer la valeur de &lt;tt class="docutils literal"&gt;sha256_hash&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;C'est tout pour moi !&lt;/p&gt;
</content><category term="til"/><category term="til"/><category term="django"/></entry><entry><title>TIL: Django constraints</title><link href="https://sarahabd.com/til/django-constraints" rel="alternate"/><published>2023-08-12T10:00:00+02:00</published><updated>2023-08-12T10:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2023-08-12:/til/django-constraints</id><summary type="html">&lt;p class="first last"&gt;I have done some work with constraints recently and I wanted to write something on it just to remind myself.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi there,&lt;/p&gt;
&lt;p&gt;I have done some work with constraint recently and I wanted to write
something on it just to remind myself. I hope it’s useful to you too.&lt;/p&gt;
&lt;p&gt;Database constraints are really useful to make sure each row is valid
before to save it. You have two type of constraints you can use just
before to record a new line in a table in Django: &lt;tt class="docutils literal"&gt;CheckConstraint&lt;/tt&gt;
and &lt;tt class="docutils literal"&gt;UniqueConstraint&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;I use PostgreSQL which has powerful tools, you can set database
constraint according what is implemented by Django.&lt;/p&gt;
&lt;p&gt;Explanations are always better with an example so here is a constraint
to avoid date overlapping between the start date and the end date:&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;start_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;end_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;   &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;constraints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;         &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CheckConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;               &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Q&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start_at__lt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;end_at&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;               &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'start_at_before_end_at'&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="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UniqueConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;               &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'start_date'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'end_date'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;               &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'unique_event_dates'&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;/pre&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;CheckConstraint&lt;/tt&gt; ensures that the &lt;tt class="docutils literal"&gt;start_at&lt;/tt&gt; is before the
&lt;tt class="docutils literal"&gt;end_at&lt;/tt&gt;. The &lt;tt class="docutils literal"&gt;UniqueConstraint&lt;/tt&gt; ensures that there are no two
events with the same &lt;tt class="docutils literal"&gt;start_date&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;end_date&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;I discovered that if you want to make a &lt;tt class="docutils literal"&gt;UniqueConstraint&lt;/tt&gt; in Django,
it considers &lt;tt class="docutils literal"&gt;NULL&lt;/tt&gt; values as distinct, which I didn’t want in my
case.&lt;/p&gt;
&lt;p&gt;Going back to my previous example, here we have 2 records:&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="9%" /&gt;
&lt;col width="45%" /&gt;
&lt;col width="45%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head"&gt;id&lt;/th&gt;
&lt;th class="head"&gt;start_date&lt;/th&gt;
&lt;th class="head"&gt;end_date&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;2019-12-31&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;2019-12-31&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Both have the same &lt;tt class="docutils literal"&gt;end_date&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;start_date&lt;/tt&gt; set to &lt;tt class="docutils literal"&gt;NULL&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;These two records will be considered unique because a NULL is not equal
to another &lt;tt class="docutils literal"&gt;NULL&lt;/tt&gt; in SQL, so the two records are considered distinct.&lt;/p&gt;
&lt;p&gt;You can use &lt;tt class="docutils literal"&gt;WITH DISTINCT NULL VALUES&lt;/tt&gt; with PostgreSQL 15 but in my
case I was using an older version, of course,&amp;nbsp; so I needed to use
another option.&lt;/p&gt;
&lt;p&gt;If you want to make sure that &lt;tt class="docutils literal"&gt;NULL&lt;/tt&gt; values are not considered
distinct in the &lt;tt class="docutils literal"&gt;UniqueConstraint&lt;/tt&gt;, you can use the hash function with
the unique=True attribute instead.&lt;/p&gt;
&lt;p&gt;Here is an example of the hash function with the unique value based on
the previous code with the Event class. A &lt;tt class="docutils literal"&gt;sha256_hash&lt;/tt&gt; field which
combines all the fields I want in an hash:&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;hashlib&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;json&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;start_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;end_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;fancy_field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;sha256_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BinaryField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&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="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;__save__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__save__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sha256_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compute_sha256_hash&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;   &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;compute_sha256_hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;json_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;         &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;         &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;               &lt;span class="s2"&gt;&amp;quot;start_at&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;               &lt;span class="s2"&gt;&amp;quot;end_at&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;               &lt;span class="s2"&gt;&amp;quot;fancy_field&amp;quot;&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="c1"&gt;# Forces datetime to use timestamp due to inconsistency&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="c1"&gt;# in timezone format.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;json_object&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;start_at&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_at&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;json_object&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;end_at&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end_at&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;      &lt;span class="n"&gt;json_repr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;         &lt;span class="n"&gt;json_object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;         &lt;span class="n"&gt;sort_keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;         &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;         &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DjangoJSONEncoder&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json_repr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;sha256_hash&lt;/tt&gt; is unique and shouldn’t allow null values, but with
the &lt;tt class="docutils literal"&gt;blank=True&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;null=True&lt;/tt&gt; attributes, it can have null
values. It’s needed then to populate the existing values if there are
some.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What if there is existing data in the table?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;sha256_hash&lt;/tt&gt; is unique and shouldn’t allow null values, but with
the &lt;tt class="docutils literal"&gt;blank=True&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;null=True&lt;/tt&gt; attributes, it can have null
values. It’s needed then to populate the existing values if there are
some.&lt;/p&gt;
&lt;p&gt;In order to do that, we change the attribute to allow null values :&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;start_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;end_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;fancy_field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;   &lt;span class="n"&gt;sha256_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BinaryField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;      &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&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="err"&gt;…&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;After that, we can populate the value with a django command in by
filtering the existing Event table where the field &lt;tt class="docutils literal"&gt;sha256_hash&lt;/tt&gt; is
null, and call the method in order the create the &lt;tt class="docutils literal"&gt;sha256_hash&lt;/tt&gt; value
with the method &lt;tt class="docutils literal"&gt;compute_sha256_hash&lt;/tt&gt; of the class.&lt;/p&gt;
&lt;p&gt;That’s it for me!&lt;/p&gt;
</content><category term="til"/><category term="til"/><category term="django"/></entry><entry><title>DjangoCon Europe 2023 : de participante à organisatrice</title><link href="https://sarahabd.com/fr/blog/djangocon-europe-2023-from-attendee-to-organizer" rel="alternate"/><published>2023-06-14T14:36:00+02:00</published><updated>2023-06-14T14:36:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2023-06-14:/fr/blog/djangocon-europe-2023-from-attendee-to-organizer</id><summary type="html">&lt;p class="first last"&gt;Bonjour, j'espère que vous allez bien. Il y a quelques semaines, j'étais à la DjangoCon Europe à Édimbourg...&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour, j'espère que vous allez bien. Il y a quelques semaines, j'étais à la DjangoCon Europe à Édimbourg.
Je ne suis pas sûre d'être complètement remise de la fatigue, mais c'était génial !&lt;/p&gt;
&lt;p&gt;Je suis accro à cet événement. Ma première DjangoCon, c'était en 2021, à distance à cause du COVID, et beaucoup
de gens m'ont dit « c'est vraiment différent en vrai, tu devrais absolument essayer au moins une fois ».&lt;/p&gt;
&lt;p&gt;Et... je l'ai fait !&lt;/p&gt;
&lt;p&gt;J'ai participé à la DjangoCon Europe l'année dernière à Porto, c'était incroyable.
J'ai vraiment aimé la conférence et rencontrer des gens, dont certains à qui j'avais parlé virtuellement,
alors c'était une vraie joie de les voir en personne. C'était génial. Cette conférence m'a aidée à
m'impliquer davantage dans la communauté et à apprendre énormément de choses.
Pour être honnête, mon anglais n'est pas parfait, mais j'ai réussi à comprendre et à me faire comprendre.
Si vous n'êtes jamais allé·e à une DjangoCon, vous devriez absolument y aller. Ça en vaut vraiment la peine.&lt;/p&gt;
&lt;p&gt;Ce qu'il faut savoir, c'est que chaque DjangoCon Europe est organisée par des bénévoles, et que les responsables doivent
envoyer une proposition à la &lt;a class="reference external" href="https://www.djangoproject.com/foundation/"&gt;Django Software Foundation&lt;/a&gt;
(DSF) pour la faire approuver. Cette conférence a failli ne pas avoir lieu, si vous regardez l'article de la DSF à ce sujet.
Je ne voulais pas que ça arrive, alors je me suis proposée comme bénévole. J'ai rejoint l'équipe en place, en particulier
pour le site web, et pour faire partie de l'équipe du code de conduite 💖&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="L'équipe du code de conduite 2023, de gauche à droite, Thibaud Colas, Sage Abdullah, moi et Tom Carrick tenant le panneau du code de conduite" src="/images/coc-team-2023.jpg" /&gt;
&lt;p class="caption"&gt;© 2023 Thibaud Colas CC BY-NC-SA - Équipe du code de conduite de la DjangoCon 2023&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Être organisatrice, c'est une autre façon de s'amuser. On ne profite pas de la conférence de la même manière, ça peut être
épuisant, mais on apprécie vraiment de voir la conférence se dérouler et être un succès,
surtout quand on sait tout ce qui s'est passé en coulisses.&lt;/p&gt;
&lt;p&gt;Quand on regarde les gens :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;se rencontrer et rire ensemble&lt;/li&gt;
&lt;li&gt;trouver leur futur emploi&lt;/li&gt;
&lt;li&gt;se faire de nouveaux amis&lt;/li&gt;
&lt;li&gt;trouver de l'aide pour un projet précis&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C'est une joie inestimable ✨&lt;/p&gt;
&lt;p&gt;J'ai appris beaucoup de choses en étant « de l'autre côté ».&lt;/p&gt;
&lt;p&gt;Je ne mesurais pas à quel point il est difficile d'obtenir un visa selon le pays d'où l'on vient.
Les règles sont toujours différentes. Je n'imaginais pas à quel point organiser un événement
à distance peut coûter cher quand on a des fonds limités. Chaque détail compte quand on essaie de faire le meilleur événement pour tout le monde.&lt;/p&gt;
&lt;p&gt;Je suis vraiment heureuse de faire partie de cette communauté, et j'espère faire de mon mieux pour accueillir les gens
et être aussi bienveillante qu'on l'a été avec moi.&lt;/p&gt;
&lt;p&gt;Si vous souhaitez rendre à Django et à la communauté ce qu'ils vous ont apporté, pensez à la DjangoCon
Europe 2024. Être organisateur·rice ou bénévole est une excellente façon de contribuer,
et ça ne demande pas de savoir coder.&lt;/p&gt;
&lt;p&gt;Je terminerai cet article en disant : « je suis venue pour une conférence, je suis restée pour la communauté » 💚&lt;/p&gt;
</content><category term="blog"/><category term="django"/><category term="djangocon"/><category term="reflexion"/></entry><entry><title>DjangoCon Europe 2023: from attendee to organizer</title><link href="https://sarahabd.com/blog/djangocon-europe-2023-from-attendee-to-organizer" rel="alternate"/><published>2023-06-14T14:36:00+02:00</published><updated>2023-06-14T14:36:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2023-06-14:/blog/djangocon-europe-2023-from-attendee-to-organizer</id><summary type="html">&lt;p class="first last"&gt;Hi there, I hope you’re fine. A few weeks ago, I was at DjangoCon Europe in Edinburgh...&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi there, I hope you’re fine. A few weeks ago, I was at DjangoCon Europe in Edinburgh.
I’m not sure I have completely recovered from tiredness, but it was awesome!&lt;/p&gt;
&lt;p&gt;I’m hooked on this event. My first DjangoCon was in 2021 in remote, due to COVID, and many
people told me “it’s really different in real life, you should definitely try once”.&lt;/p&gt;
&lt;p&gt;And… I did!&lt;/p&gt;
&lt;p&gt;I participated in DjangoCon Europe last year in Porto, it was amazing.
I really liked the conference and meeting people, some of them that I have talked to virtually,
so there was real joy seeing them in person. It was awesome. This conference helped me to become
more involved in the community and learn so many things.
To be honest, I don’t have the best English but I was able to understand and be understood.
If you have never been to a DjangoCon, you should definitely go to one. It’s truly worth it.&lt;/p&gt;
&lt;p&gt;What you need to know is that each DjangoCon Europe is run by volunteers, and the chairs have
to send a proposal to the &lt;a class="reference external" href="https://www.djangoproject.com/foundation/"&gt;Django Software Foundation&lt;/a&gt;
(DSF) for approval. This conference almost did not happen if you see the DSF’s post about it.
I didn’t want that to happen so I proposed myself as a volunteer. I joined the current team especially
for the website and be part of the Code of Conduct team 💖&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="2023 CoC Team, from left to right, Thibaud Colas, Sage Abdullah, me and Tom Carrick holding the CoC Sign" src="../images/coc-team-2023.jpg" /&gt;
&lt;p class="caption"&gt;© 2023 Thibaud Colas CC BY-NC-SA - CoC Team of DjangoCon 2023&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Being an organizer is a different way of fun. You don’t enjoy the conference the same way, it can be
exhausting, but you really enjoy the fact of seeing the conference happening and being a success
especially when you know all things that happened behind the scenes.&lt;/p&gt;
&lt;p&gt;When you look at people:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;meeting and laughing together&lt;/li&gt;
&lt;li&gt;finding their future job&lt;/li&gt;
&lt;li&gt;finding new friends&lt;/li&gt;
&lt;li&gt;finding help for a specific project&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It's a priceless joy ✨&lt;/p&gt;
&lt;p&gt;I learn many things by being “on the other side”.&lt;/p&gt;
&lt;p&gt;I didn't understand how hard it is to get a visa depending on the country you're coming from.
The rules are always different. I didn’t imagine how it can cost so much to host an event
virtually when you have limited funds. Each detail counts, when trying to make the best event for everyone.&lt;/p&gt;
&lt;p&gt;I’m really glad to be part of this community, and I hope to do my best to welcome people
and be friendly as much as I've been welcomed myself.&lt;/p&gt;
&lt;p&gt;If you would like to give back to Django and the community, you should consider DjangoCon
Europe 2024 as a way to do so. Being an organizer or a volunteer is a great way to contribute,
and it doesn't require the ability to code.&lt;/p&gt;
&lt;p&gt;I will end this post by saying that “I joined a conference, I stayed for the community” 💚&lt;/p&gt;
</content><category term="blog"/><category term="django"/><category term="djangocon"/><category term="reflexion"/></entry><entry><title>Migration de Gatsby vers Pelican</title><link href="https://sarahabd.com/fr/blog/migration-from-gatsby-to-pelican" rel="alternate"/><published>2023-04-21T18:00:00+02:00</published><updated>2023-04-21T18:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2023-04-21:/fr/blog/migration-from-gatsby-to-pelican</id><summary type="html">&lt;p class="first last"&gt;Du JS au Python, migration de génération de site statique, de Gatsby à Pelican&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour... ça fait un moment, premier article de 2023, youpi !
J'ai tellement de choses à raconter, mais je vais commencer par le premier
sujet sur lequel j'ai mis longtemps à écrire : mon blog.&lt;/p&gt;
&lt;p&gt;J'ai changé de framework, en passant de &lt;a class="reference external" href="http://Gatsby.js"&gt;Gatsby.js&lt;/a&gt;
à &lt;a class="reference external" href="https://getpelican.com/"&gt;Pelican&lt;/a&gt;.&lt;/p&gt;
&lt;div class="section" id="pourquoi-migrer-mon-blog"&gt;
&lt;h2&gt;Pourquoi migrer mon blog ?&lt;/h2&gt;
&lt;p&gt;Bonne question ! Comme je fais de plus en plus de Python, il me
semblait plus logique d'avoir un blog en Python.
En plus, c'est plus simple à maintenir puisque
j'utilise ce langage tous les jours. Je voulais aussi avoir moins
de dépendances.&lt;/p&gt;
&lt;p&gt;Mon site avec Gatsby avait beaucoup de dépendances, vous pouvez
le voir avec mon &lt;cite&gt;package.json&lt;/cite&gt;. Comparez maintenant avec
le &lt;cite&gt;requirements.txt&lt;/cite&gt;.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="dépendances du package.json vs requirements.txt" src="/images/dependencies.png" /&gt;
&lt;p class="caption"&gt;Dépendances du package.json vs dépendances du requirements.txt&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Comme vous pouvez le voir, le changement est énorme, et il s'agit des dépendances
et des dépendances de développement, sans afficher les sous-dépendances.&lt;/p&gt;
&lt;p&gt;Je devais passer à Gatsby V3, car mon projet avait trop
de dépendances que je ne pouvais pas mettre à jour. Certaines sont tout simplement
de vieilles dépendances qui ne sont plus maintenues.&lt;/p&gt;
&lt;p&gt;Sinon, je devais mettre à jour mon projet Gatsby, et j'avais
trop de conflits de dépendances, car j'avais utilisé un starter
pour créer mon blog, et ce starter n'est pas entièrement
compatible avec les dernières versions de Gatsby. Je sais à quel point
il peut être difficile de maintenir un projet, surtout quand on est
seul·e. J'aurais pu contribuer, mais à mon avis je ne fais pas assez
de Gatsby pour ça.&lt;/p&gt;
&lt;p&gt;J'ai finalement décidé de passer à autre chose.&lt;/p&gt;
&lt;p&gt;J'ai choisi d'utiliser Pelican, c'est plutôt sympa. Il existe des
plugins pour améliorer son site, et j'en ai utilisé un pour
importer le contenu existant d'un autre site. Je m'en suis servie
pour déplacer mon blog, c'est génial ! La documentation complète est
&lt;a class="reference external" href="https://docs.getpelican.com/en/latest/importer.html"&gt;ici&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;J'ai utilisé un thème personnalisé, créé par mes soins, pour avoir le
style que je voulais. Je l'ai fait correspondre à mon ancien blog pour que
les gens ne remarquent pas que je suis passée à Pelican. Vous pouvez trouver des
&lt;a class="reference external" href="https://github.com/getpelican/pelican-themes"&gt;thèmes&lt;/a&gt; déjà prêts,
ou un thème de base à partir duquel créer le vôtre. La documentation
donne quelques conseils pour créer votre propre thème.&lt;/p&gt;
&lt;p&gt;J'ai donc commencé avec un thème existant et j'ai modifié les éléments suivants :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Revoir les templates pour qu'ils correspondent à ce que je veux&lt;/li&gt;
&lt;li&gt;Ajouter les pages manquantes&lt;/li&gt;
&lt;li&gt;Modifier mon style CSS et mon JavaScript&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La partie amusante, c'était de convertir ce qu'il fallait de
React.js en pur JS, pour avoir moins de dépendances et un code
plus simple, car il me manquait certaines choses sur mon site :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;L'animation de la page d'accueil&lt;/li&gt;
&lt;li&gt;Le bouton pour basculer en mode sombre&lt;/li&gt;
&lt;li&gt;Un peu de JS pour la personnalisation (ajustement d'accessibilité pour aria-label)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Une fois que c'était fait, j'ai ajouté quelques plugins pour améliorer le
site, comme le SEO ou les articles similaires dans un article.
Vous pouvez trouver les
&lt;a class="reference external" href="https://github.com/getpelican/pelican-plugins"&gt;plugins dans l'organisation Pelican&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Et voilà ! ✨&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="exemples"&gt;
&lt;h2&gt;Exemples&lt;/h2&gt;
&lt;p&gt;Je sais que certain·es d'entre vous vont dire : c'est cool, Sarah, mais y a-t-il
d'autres sites qui utilisent Pelican ?&lt;/p&gt;
&lt;p&gt;Oui, il y en a ! Voici les personnes que je connais qui utilisent
Pelican, mais j'imagine qu'il existe d'autres sites :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Adam Johnson - &lt;a class="reference external" href="https://adamj.eu/"&gt;https://adamj.eu/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Julien Palard - &lt;a class="reference external" href="https://mdk.fr/"&gt;https://mdk.fr/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Justin Mayer, créateur de Pelican - &lt;a class="reference external" href="https://justinmayer.com/"&gt;https://justinmayer.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Paolo Melchiorre - &lt;a class="reference external" href="https://www.paulox.net/"&gt;https://www.paulox.net/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tom Carrick - &lt;a class="reference external" href="https://carrick.eu/"&gt;https://carrick.eu/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="apprentissages-et-progres"&gt;
&lt;h2&gt;Apprentissages et progrès&lt;/h2&gt;
&lt;p&gt;Cette migration n'a pas été aussi difficile que je le pensais.
Je l'ai faite en quelques jours, répartis sur mon temps libre,
car je n'avais pas beaucoup de temps à y consacrer, mais je
pense que j'aurais pu aller plus vite. Trop de choses à
faire, pas assez de temps.&lt;/p&gt;
&lt;p&gt;C'était amusant de créer le thème du blog et de voir
comment Pelican génère les templates, c'est vraiment bien.
En plus, j'ai ajouté des catégories et une section TIL, il
faut que j'ajoute d'autres articles, mais c'est un autre sujet.
Pelican permet de créer facilement des catégories et de
modifier ou supprimer des éléments comme on veut.
Il est facilement personnalisable selon vos besoins.&lt;/p&gt;
&lt;p&gt;Avoir moins de dépendances est clairement un bon point
pour moi : moins de problèmes, et c'est plus facile à maintenir.
Je suppose que je suis comme beaucoup de gens qui aiment leur blog
mais ne peuvent pas y consacrer beaucoup de temps.&lt;/p&gt;
&lt;p&gt;Pelican est vraiment simple à utiliser. Je n'ai pas l'habitude
d'écrire en &lt;cite&gt;rst&lt;/cite&gt;, mais ça ne change pas grand-chose par rapport au &lt;cite&gt;markdown&lt;/cite&gt;.
Notez que vous pouvez changer le format des articles
si besoin, mais la plupart des documentations open source
pour Python utilisent le &lt;cite&gt;rst&lt;/cite&gt;, donc ce n'est pas un problème pour moi.&lt;/p&gt;
&lt;p&gt;J'ai aussi eu le temps d'améliorer un peu l'accessibilité
de mon blog. Ce n'est clairement pas terminé, mais j'ai eu
le temps de faire quelques corrections, ce qui est cool.&lt;/p&gt;
&lt;p&gt;Je peux maintenant faire des brouillons d'articles, ce qui est vraiment pratique,
car je demande à des personnes de relire mes articles quand elles
en ont envie, puisque l'anglais n'est pas ma langue
maternelle. Du coup, vous ne trouverez pas mon blog sur GitHub,
désolée.&lt;/p&gt;
&lt;p&gt;Je recommande Pelican, je n'ai trouvé aucun inconvénient jusqu'ici.&lt;/p&gt;
&lt;p&gt;La prochaine étape sera d'améliorer encore l'accessibilité
et d'ajouter plus d'articles, bien sûr !&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/></entry><entry><title>Migration from Gatsby to Pelican</title><link href="https://sarahabd.com/blog/migration-from-gatsby-to-pelican" rel="alternate"/><published>2023-04-21T18:00:00+02:00</published><updated>2023-04-21T18:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2023-04-21:/blog/migration-from-gatsby-to-pelican</id><summary type="html">&lt;p class="first last"&gt;From JS to Python, migration static website generation, Gatsby to Pelican&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi here... it's been a while, first post of 2023 yay!
I have so much to talk about but I'll start with the first
topic that took me a long time to write about: my blog.&lt;/p&gt;
&lt;p&gt;I switched frameworks from &lt;a class="reference external" href="http://Gatsby.js"&gt;Gatsby.js&lt;/a&gt;
to &lt;a class="reference external" href="https://getpelican.com/"&gt;Pelican&lt;/a&gt;.&lt;/p&gt;
&lt;div class="section" id="why-migrate-my-blog"&gt;
&lt;h2&gt;Why migrate my blog ?&lt;/h2&gt;
&lt;p&gt;Good question, as I’m doing more and more python, it
seems more logical to have a blog in python.
Besides, it’s simpler to maintain since I
use the language everyday. I also wanted to have fewer
dependencies.&lt;/p&gt;
&lt;p&gt;My website with Gatsby had many dependencies, you can
see that with my &lt;cite&gt;package.json&lt;/cite&gt;. Now compare that to
the &lt;cite&gt;requirements.txt&lt;/cite&gt;.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="package.json dependencies vs requirements.txt" src="../images/dependencies.png" /&gt;
&lt;p class="caption"&gt;package.json dependencies vs requirements.txt dependencies&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;As you can see, the change is huge, it's the dependencies
and dev-dependencies without displaying sub-dependencies.&lt;/p&gt;
&lt;p&gt;I needed to move to Gatsby V3 because my project had too
many dependencies which I cannot update. Some are simply
old dependencies that are no longer maintained.&lt;/p&gt;
&lt;p&gt;Otherwise, I had to upgrade my Gatsby project and I had
too many dependencies conflicts since I used a starter
in order to create my blog and the starter is not fully
compatible with latest versions of Gatsby. I know how it
can be hard to maintain a project, especially when you're
alone. I could have contributed but i’m not doing enough
Gatsby to do so in my opinion.&lt;/p&gt;
&lt;p&gt;I finally decided to move to something else.&lt;/p&gt;
&lt;p&gt;I choose to use Pelican, it’s pretty nice. There are
plugins to improve your website and I used one of them to
import existing content from another website. I used it
to move my blog, it’s great! You have the full documentation
&lt;a class="reference external" href="https://docs.getpelican.com/en/latest/importer.html"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I used a custom theme, created by me, to have the
style I wanted. I made it correspond to my previous blog so that
people won’t notice I changed to Pelican. You can find already
built-in &lt;a class="reference external" href="https://github.com/getpelican/pelican-themes"&gt;themes&lt;/a&gt;
or basic theme to create your own theme from. You can get some
guidance ton creating your own theme in the documentation.&lt;/p&gt;
&lt;p&gt;So I started from an existing theme and I change the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Review templates to correspond to what I want&lt;/li&gt;
&lt;li&gt;Add missing pages&lt;/li&gt;
&lt;li&gt;Change my CSS style and JavaScript&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The fun part was to change the needed things from
React.js to pure JS to get less dependencies and simple
code because I'm missing some things in my website:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The animation on the homepage&lt;/li&gt;
&lt;li&gt;The toggle theme for dark mode&lt;/li&gt;
&lt;li&gt;Few JS for customisation (accessibility tweak for aria-label)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After that was done, I added some plugins to improve the
website like SEO, or posts related in an article,
you can find the
&lt;a class="reference external" href="https://github.com/getpelican/pelican-plugins"&gt;plugins in the pelican organization&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And that’s it ! ✨&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="examples"&gt;
&lt;h2&gt;Examples&lt;/h2&gt;
&lt;p&gt;I know some of you will say, cool Sarah but are there
other websites using Pelican ?&lt;/p&gt;
&lt;p&gt;Yes, there are ! These are the people I know that use
Pelican, but I imagine there are other websites:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Adam Johnson - &lt;a class="reference external" href="https://adamj.eu/"&gt;https://adamj.eu/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Julien Palard - &lt;a class="reference external" href="https://mdk.fr/"&gt;https://mdk.fr/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Justin Mayer, creator of Pelican - &lt;a class="reference external" href="https://justinmayer.com/"&gt;https://justinmayer.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Paolo Melchiorre - &lt;a class="reference external" href="https://www.paulox.net/"&gt;https://www.paulox.net/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tom Carrick - &lt;a class="reference external" href="https://carrick.eu/"&gt;https://carrick.eu/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="learning-and-improvements"&gt;
&lt;h2&gt;Learning and improvements&lt;/h2&gt;
&lt;p&gt;This migration was not as difficult as I expected.
I did it in a few days split up on my free time that
I had because I didn't have much time for it, but I
think I could have done it faster. Too many stuff to
do, not enough time.&lt;/p&gt;
&lt;p&gt;It was fun to create the theme for the blog and see
how Pelican generates templates, it’s really nice.
Besides, I added some categories and a TIL section, I
need to add other articles but that’s another point.
Pelican makes it easy to create categories and
update/remove some stuff as you want.
It’s easily customizable to fit your needs.&lt;/p&gt;
&lt;p&gt;Having less dependencies is clearly a good point
for me, less issues and better for maintaining.
I guess I’m like many people who like their blog
but can’t dedicate much time  to it.&lt;/p&gt;
&lt;p&gt;Pelican is really simple to use, I'm not used to
writing in &lt;cite&gt;rst&lt;/cite&gt; but it doesn't change much from &lt;cite&gt;markdown&lt;/cite&gt;.
Note that you can change the type of the articles
if needed, but most  documentation in open source
for Python use &lt;cite&gt;rst&lt;/cite&gt; so it's not a big deal for me.&lt;/p&gt;
&lt;p&gt;I also have time to improve a bit the accessibility
of my blog, clearly not completely done but I had
time to make few corrections, which is cool.&lt;/p&gt;
&lt;p&gt;I can now do draft articles, which is really cool
because I ask people to read articles when they
are willing to do so, since I’m not a native English
speaker. So, you can’t find my blog on GitHub,
sorry for that.&lt;/p&gt;
&lt;p&gt;I recommend Pelican, I don’t have any drawbacks so far.&lt;/p&gt;
&lt;p&gt;Next step will be to improve accessibility again
and add more articles of course !&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/></entry><entry><title>TIL : le gitignore global</title><link href="https://sarahabd.com/fr/til/global-gitignore" rel="alternate"/><published>2022-07-12T10:10:00+02:00</published><updated>2022-07-12T10:10:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2022-07-12:/fr/til/global-gitignore</id><summary type="html">&lt;p class="first last"&gt;Bonjour ! J'ai découvert qu'on peut configurer git pour exclure des fichiers ou des dossiers de manière globale, ce qui permet que le gitignore du projet…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour !&lt;/p&gt;
&lt;p&gt;J'ai découvert qu'on peut configurer git pour exclure des fichiers ou des dossiers
de manière globale. C'est utile pour que le gitignore du projet ne contienne que ce
qui concerne le projet, et pas ce qui dépend du système d'exploitation ou de l'éditeur de chaque membre de l'équipe.&lt;/p&gt;
&lt;p&gt;Devinez quoi, vous pouvez ignorer des choses globalement de votre côté sans avoir
besoin de les commiter dans le gitignore du projet. Je vous explique comment !&lt;/p&gt;
&lt;p&gt;Tout d'abord, il faut créer un fichier dans le répertoire personnel. On peut
lui donner le nom qu'on veut, mais pour savoir facilement ce que c'est,
appelons-le : &lt;tt class="docutils literal"&gt;.gitignore_global&lt;/tt&gt;.&lt;/p&gt;
&lt;pre class="code sh literal-block"&gt;
touch&lt;span class="w"&gt; &lt;/span&gt;~/.gitignore_global
&lt;/pre&gt;
&lt;p&gt;Ensuite, ajoutez dans ce fichier tout ce que vous voulez exclure :&lt;/p&gt;
&lt;pre class="code sh literal-block"&gt;
.DS_Store&lt;span class="w"&gt;
&lt;/span&gt;.vs_code
&lt;/pre&gt;
&lt;p&gt;Voici le mien, j'utilise un Mac et VS Code, mais il faut l'adapter à
&lt;strong&gt;votre système d'exploitation et aux fichiers de votre éditeur.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Enfin, configurez git pour qu'il sache que les fichiers globaux à exclure se trouvent
à cet emplacement :&lt;/p&gt;
&lt;pre class="code sh literal-block"&gt;
git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;--global&lt;span class="w"&gt; &lt;/span&gt;core.excludesfile&lt;span class="w"&gt; &lt;/span&gt;~/.gitignore_global
&lt;/pre&gt;
&lt;p&gt;Pour les utilisateurs et utilisatrices de Windows, c'est légèrement différent :&lt;/p&gt;
&lt;pre class="code sh literal-block"&gt;
git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;--global&lt;span class="w"&gt; &lt;/span&gt;core.excludesfile&lt;span class="sb"&gt;``&lt;/span&gt;%USERPROFILE%&lt;span class="se"&gt;\.&lt;/span&gt;gitignore_global
&lt;/pre&gt;
&lt;p&gt;C'est tout pour le moment ! J'espère que ça sera utile à quelqu'un :)&lt;/p&gt;
</content><category term="til"/><category term="til"/><category term="howto"/></entry><entry><title>TIL: Global gitignore</title><link href="https://sarahabd.com/til/global-gitignore" rel="alternate"/><published>2022-07-12T10:10:00+02:00</published><updated>2022-07-12T10:10:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2022-07-12:/til/global-gitignore</id><summary type="html">&lt;p class="first last"&gt;Hi there! I found out that you can configure git to exclude files or folders globally and this is useful so that the project gitignore is…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi there!&lt;/p&gt;
&lt;p&gt;I found out that you can configure git to exclude files or folders
globally and this is useful so that the project gitignore is based only
on that and not on the operating system or editor of each team member.&lt;/p&gt;
&lt;p&gt;Guess what, you can ignore things globally on your end and you don’t
need to commit this in the gitignore of the project. I’ll tell you how!&lt;/p&gt;
&lt;p&gt;First of all, you need to create a file in the home directory, we can
call it with any name we want but just to know easily what it is, let’s
call it: &lt;tt class="docutils literal"&gt;.gitignore_global&lt;/tt&gt;.&lt;/p&gt;
&lt;pre class="code sh literal-block"&gt;
touch&lt;span class="w"&gt; &lt;/span&gt;~/.gitignore_global
&lt;/pre&gt;
&lt;p&gt;And then add in the file all the things you want to exclude:&lt;/p&gt;
&lt;pre class="code sh literal-block"&gt;
.DS_Store&lt;span class="w"&gt;
&lt;/span&gt;.vs_code
&lt;/pre&gt;
&lt;p&gt;This is mine, I use Mac and Vs Code, but you need to match it with your
&lt;strong&gt;operating system and your editor files.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Finally, configure git to know that the global files to exclude are in
this path:&lt;/p&gt;
&lt;pre class="code sh literal-block"&gt;
git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;--global&lt;span class="w"&gt; &lt;/span&gt;core.excludesfile&lt;span class="w"&gt; &lt;/span&gt;~/.gitignore_global
&lt;/pre&gt;
&lt;p&gt;For windows users, it’s slightly different:&lt;/p&gt;
&lt;pre class="code sh literal-block"&gt;
git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;--global&lt;span class="w"&gt; &lt;/span&gt;core.excludesfile&lt;span class="sb"&gt;``&lt;/span&gt;%USERPROFILE%&lt;span class="se"&gt;\.&lt;/span&gt;gitignore_global
&lt;/pre&gt;
&lt;p&gt;That’s it for now! I hope it will be useful for someone :)&lt;/p&gt;
</content><category term="til"/><category term="til"/><category term="howto"/></entry><entry><title>TIL : ressources sur l'accessibilité</title><link href="https://sarahabd.com/fr/til/accessibility-resources" rel="alternate"/><published>2022-05-07T10:00:00+02:00</published><updated>2022-05-07T10:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2022-05-07:/fr/til/accessibility-resources</id><summary type="html">&lt;p class="first last"&gt;Bonjour, j'ai décidé de lancer une série de TIL (Today I Learned) ! Rodrigo, auteur du blog Mathspp, m'a donné envie de le faire avec sa série de TIL…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour,&lt;/p&gt;
&lt;p&gt;J'ai décidé de lancer une série de TIL (Today I Learned) !&lt;/p&gt;
&lt;p&gt;Rodrigo, auteur du blog &lt;a class="reference external" href="https://mathspp.com/"&gt;Mathspp&lt;/a&gt;, m'a donné envie
de le faire avec sa série de TIL. Comme je le lui ai dit, je vais le faire pour
m'aider à me souvenir de certaines choses et partager ce que j'ai découvert avec toutes les personnes
que ça pourrait intéresser. Je lui dédie mon premier TIL d'une série que
j'espère belle.&lt;/p&gt;
&lt;p&gt;J'ai commencé à créer un mode sombre pour le projet Django et je me suis retrouvée face à un
sujet intéressant : l'accessibilité.&lt;/p&gt;
&lt;p&gt;C'est un sujet auquel je suis sensible, mais j'ai découvert que j'ai énormément de choses
à apprendre ! Même mon site est vraiment mauvais en matière d'accessibilité... mais j'ai
découvert des ressources très utiles qui méritent d'être notées
quelque part.&lt;/p&gt;
&lt;p&gt;L'accessibilité concerne de nombreux cas : &lt;em&gt;tritanopie&lt;/em&gt;, &lt;em&gt;deutéranomalie&lt;/em&gt;, etc.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://whocanuse.com/"&gt;Whocanuse&lt;/a&gt; repose sur le même principe que
&lt;a class="reference external" href="https://caniuse.com/"&gt;Caniuse&lt;/a&gt;, mais pour l'accessibilité et le contraste.&lt;/p&gt;
&lt;p&gt;C'est vraiment utile pour voir la simulation des couleurs pour chaque type de
vision et le contraste avec une autre couleur. Ça m'aide vraiment à mieux
ajuster le contraste des couleurs.&lt;/p&gt;
&lt;p&gt;Remarque : vous pouvez aussi voir le contraste et le ratio des couleurs dans les devtools de Chrome :&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="contraste dans les devtools de Chrome" src="/images/devtools-chrome.png" /&gt;
&lt;p class="caption"&gt;Contraste dans les devtools de Chrome&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Il y a aussi &lt;a class="reference external" href="https://kontrasto.netlify.app/"&gt;Kontrasto&lt;/a&gt;, créé par
Thibaud Colas, qui s'intéresse de près à l'accessibilité 🙂&lt;/p&gt;
&lt;p&gt;C'est vraiment bien de voir une façon d'améliorer l'accessibilité avec les images.&lt;/p&gt;
&lt;p&gt;J'ai aussi découvert &lt;a class="reference external" href="https://webaim.org/resources/linkcontrastchecker/"&gt;Link Contrast
Checker&lt;/a&gt;, un site
qui permet de vérifier le contraste des liens pour s'assurer qu'il n'y a pas
de problème d'accessibilité.&lt;/p&gt;
&lt;p&gt;J'ai trouvé cette &lt;a class="reference external" href="https://www.a11yproject.com/checklist/"&gt;checklist
d'accessibilité&lt;/a&gt;, qui peut être un
bon point de départ pour rendre votre site plus inclusif et repérer des points que vous
auriez manqués.&lt;/p&gt;
&lt;p&gt;Comme je suis une grande fan des pipelines, il existe aussi des outils pour vérifier
l'accessibilité avec une extension de navigateur ou en intégration continue :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.deque.com/axe/"&gt;aXe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://pa11y.org/"&gt;pa11y&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C'est tout pour le moment ! J'espère que ça sera utile à quelqu'un.&lt;/p&gt;
</content><category term="til"/><category term="til"/><category term="accessibility"/><category term="resources"/></entry><entry><title>TIL: Accessibility resources</title><link href="https://sarahabd.com/til/accessibility-resources" rel="alternate"/><published>2022-05-07T10:00:00+02:00</published><updated>2022-05-07T10:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2022-05-07:/til/accessibility-resources</id><summary type="html">&lt;p class="first last"&gt;Hi there, I decided to start TIL (Today I Learned) series ! Rodrigo, author of Mathspp blog, give me envy to do so with his TIL series…&lt;/p&gt;
</summary><content type="html">&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 class="reference external" 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 class="reference external" href="https://whocanuse.com/"&gt;Whocanuse&lt;/a&gt;, is based on the same purpose of
&lt;a class="reference external" 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;div class="figure"&gt;
&lt;img alt="devtools chrome contrast" src="../images/devtools-chrome.png" /&gt;
&lt;p class="caption"&gt;devtools chrome contrast&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;You also have &lt;a class="reference external" 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 class="reference external" 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 class="reference external" 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 class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.deque.com/axe/"&gt;aXe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" 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;
</content><category term="til"/><category term="til"/><category term="accessibility"/><category term="resources"/></entry><entry><title>2021, le bilan de l'année</title><link href="https://sarahabd.com/fr/blog/2021-year-in-review" rel="alternate"/><published>2022-01-30T10:00:00+01:00</published><updated>2022-01-30T10:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2022-01-30:/fr/blog/2021-year-in-review</id><summary type="html">&lt;p class="first last"&gt;Bonjour, ça fait un moment... Tout d'abord, je vous souhaite une bonne année, meilleurs vœux !! Merci à Katherine Michel et…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour, ça fait un moment... Tout d'abord, je vous souhaite une bonne
année, meilleurs vœux !!&lt;/p&gt;
&lt;p&gt;Merci à &lt;a class="reference external" href="https://github.com/KatherineMichel"&gt;Katherine Michel&lt;/a&gt;
et &lt;a class="reference external" href="https://github.com/dawnwages"&gt;Dawn Wages&lt;/a&gt; de m'avoir inspirée à écrire
un article de bilan de l'année !&lt;/p&gt;
&lt;div class="section" id="tl-dr"&gt;
&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;Cette année n'a pas été ma meilleure, mais j'ai réussi à faire des choses que je n'aurais jamais imaginé
faire.&lt;/p&gt;
&lt;p&gt;Mes temps forts de l'année :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Participer à la DjangoCon Europe et à la DjangoCon US&lt;/li&gt;
&lt;li&gt;Faire un lightning talk&lt;/li&gt;
&lt;li&gt;Réussir le challenge Hacktoberfest&lt;/li&gt;
&lt;li&gt;Contribuer à un énorme projet&lt;/li&gt;
&lt;li&gt;Découvrir une communauté incroyable et en faire partie&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="apprentissages-et-progres"&gt;
&lt;h2&gt;Apprentissages et progrès&lt;/h2&gt;
&lt;p&gt;J'ai beaucoup appris cette année, en essayant des choses, en lisant et en faisant des erreurs,
bien sûr. J'ai lu &lt;a class="reference external" href="https://adamchainz.gumroad.com/l/suydt"&gt;le livre d'Adam Johnson sur les
tests&lt;/a&gt;, qui est vraiment
intéressant. J'ai découvert que je devais changer certaines habitudes et améliorer certains
projets.&lt;/p&gt;
&lt;p&gt;J'essaie de m'impliquer davantage dans les sujets qui me tiennent à cœur ou qui
m'intéressent, par exemple les tests ou les logiciels open source.&lt;/p&gt;
&lt;p&gt;J'apprends aussi en échangeant avec les gens, même si j'ai encore un peu
de mal à tout comprendre en anglais, car je ne suis pas bilingue, mais
presque !&lt;/p&gt;
&lt;p&gt;J'ai découvert beaucoup de choses en 2021, il y a tellement de ressources :
newsletters, podcasts, comptes Twitter (oui, vraiment). En voici
quelques-unes :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://anchor.fm/djangogirls"&gt;Le podcast Django Girls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://pycoders.com/"&gt;Pycoder's weekly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Le compte Twitter de &lt;a class="reference external" href="https://twitter.com/treyhunner?t=iMH0ONBeIKZmXz2zgiRzkQ&amp;amp;s=09"&gt;Trey
Hunner&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://adamj.eu/books/"&gt;Les livres d'Adam Johnson&lt;/a&gt; et
&lt;a class="reference external" href="https://adamj.eu/tech/"&gt;son blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Et les conférences, même celles des années passées, sont vraiment intéressantes. Je
vous recommande vivement d'y jeter un œil !&lt;/p&gt;
&lt;p&gt;J'ai aussi découvert que je pouvais inspirer d'autres personnes, même si je n'ai pas l'impression d'avoir fait
quelque chose d'aussi incroyable que d'autres grandes personnes du monde du dev. On peut
inspirer même avec des choses qui ne semblent pas énormes.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conferences"&gt;
&lt;h2&gt;Conférences&lt;/h2&gt;
&lt;p&gt;J'ai assisté à ma première conférence, la DjangoCon Europe, et j'y ai donné mon
premier lightning talk ! &lt;a class="reference external" href="/fr/blog/djangocon-europe-2021-thoughts"&gt;J'ai écrit un article
ici&lt;/a&gt;. J'espère
avoir la chance d'assister à la prochaine, et en vrai cette fois :
tellement de personnes incroyables m'ont dit que c'était une expérience différente, et
j'ai vraiment envie de voir ça et de rencontrer les personnes avec qui j'ai si souvent parlé
en virtuel, haha.&lt;/p&gt;
&lt;p&gt;J'ai aussi assisté à la DjangoCon US, c'était très bien, mais je n'y suis pas restée
longtemps à cause du décalage horaire. Je voulais aider les organisateurs et organisatrices, mais je n'ai pas eu
le temps. Si vous voulez contribuer à la communauté, c'est une façon
de le faire. Beaucoup de gens pensent que tout tourne autour du code, mais il y a plein de
choses à faire à côté du code pour contribuer.&lt;/p&gt;
&lt;p&gt;J'espère pouvoir faire plus de meetups et échanger avec des gens (en
vrai, ce serait encore mieux !).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="l-hacktoberfest-en-tant-que-mainteneuse"&gt;
&lt;h2&gt;L'Hacktoberfest en tant que mainteneuse&lt;/h2&gt;
&lt;p&gt;J'ai fait l'Hacktoberfest pour la deuxième fois, mais cette fois j'étais à la fois
contributrice et mainteneuse, grâce à
&lt;a class="reference external" href="https://github.com/funbeedev"&gt;Fum&lt;/a&gt;. C'est une super expérience, même si
je n'imaginais pas à quel point ça pouvait être épuisant. En tant que contributrice, on veut que
les choses aillent vite, mais en tant que mainteneuse, c'est agréable de voir
l'engagement des gens, mais il y a tellement de choses à faire, et parfois les gens
répondent comme si le projet était toute votre vie, et je peux vous dire que
ce n'est absolument PAS le cas !&lt;/p&gt;
&lt;p&gt;Malgré ça, j'ai appris énormément de choses en faisant des revues : voir les choses
autrement, ou creuser des sujets que je connaissais mal.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="contributions-individuelles"&gt;
&lt;h2&gt;Contributions individuelles&lt;/h2&gt;
&lt;p&gt;Je pense que c'est ma meilleure année en matière de contributions à l'open source : j'ai
contribué à de nombreux projets, des petites contributions aux plus grandes. J'ai
contribué à un gros projet : Django. C'était incroyable, et j'ai aussi appris
en le faisant. Ce n'est pas une contribution impressionnante, mais j'espère qu'elle sera
utile à toutes les personnes qui utilisent ce framework incroyable ! J'espère faire
plus de contributions cette nouvelle année, en particulier dans l'écosystème Python.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="note-a-moi-meme"&gt;
&lt;h2&gt;Note à moi-même&lt;/h2&gt;
&lt;p&gt;En 2021, j'ai essayé des choses que je ne pensais pas faire un jour. Si j'avais un
conseil à donner, ce serait :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Être plus organisée&lt;/li&gt;
&lt;li&gt;Faire de son mieux, et si ce n'est pas parfait, ce n'est pas grave&lt;/li&gt;
&lt;li&gt;Contribuer, aider, écrire. Parfois, on pense que c'est bête ou inutile,
mais ça ne l'est pas pour quelqu'un d'autre&lt;/li&gt;
&lt;li&gt;L'échange, c'est de l'or. On peut apprendre des choses de quelqu'un, et cette personne
peut aussi apprendre de nous&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="reflexion"/></entry><entry><title>2021, year in review</title><link href="https://sarahabd.com/blog/2021-year-in-review" rel="alternate"/><published>2022-01-30T10:00:00+01:00</published><updated>2022-01-30T10:00:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2022-01-30:/blog/2021-year-in-review</id><summary type="html">&lt;p class="first last"&gt;Hi there, it's have been a while... First of all, I want to say happy new year to you, best wishes !! Thank you to Katherine Michel and…&lt;/p&gt;
</summary><content type="html">&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 class="reference external" href="https://github.com/KatherineMichel"&gt;Katherine Michel&lt;/a&gt;
and &lt;a class="reference external" 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;div class="section" id="tl-dr"&gt;
&lt;h2&gt;TL;DR&lt;/h2&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 class="simple"&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;/div&gt;
&lt;div class="section" id="learning-and-improvements"&gt;
&lt;h2&gt;Learning and improvements&lt;/h2&gt;
&lt;p&gt;I learn a lot this year, by trying things, reading, and do mistakes of
course. I read &lt;a class="reference external" 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 class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://anchor.fm/djangogirls"&gt;Django Girls podcast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://pycoders.com/"&gt;Pycoder’s weekly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" 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;&lt;a class="reference external" href="https://adamj.eu/books/"&gt;Adams Johnson books&lt;/a&gt; and
&lt;a class="reference external" href="https://adamj.eu/tech/"&gt;his blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;etc.&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;/div&gt;
&lt;div class="section" id="conferences"&gt;
&lt;h2&gt;Conferences&lt;/h2&gt;
&lt;p&gt;I have attend to my first conference, DjangoCon Europe, and gave my
first lighting talk ! &lt;a class="reference external" href="https://sarahabd.com/blog/djangocon-europe-2021-thoughts/"&gt;I have wrote a post
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;/div&gt;
&lt;div class="section" id="hacktoberfest-as-maintainer"&gt;
&lt;h2&gt;Hacktoberfest as maintainer&lt;/h2&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 class="reference external" 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;/div&gt;
&lt;div class="section" id="individuals-contributions"&gt;
&lt;h2&gt;Individuals contributions&lt;/h2&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;/div&gt;
&lt;div class="section" id="reminder-to-myself"&gt;
&lt;h2&gt;Reminder to myself&lt;/h2&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 class="simple"&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;
&lt;/div&gt;
</content><category term="blog"/><category term="reflexion"/></entry><entry><title>Mes impressions sur la DjangoCon Europe 2021</title><link href="https://sarahabd.com/fr/blog/djangocon-europe-2021-thoughts" rel="alternate"/><published>2021-06-07T12:00:00+02:00</published><updated>2021-06-07T12:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2021-06-07:/fr/blog/djangocon-europe-2021-thoughts</id><summary type="html">&lt;p class="first last"&gt;Bonjour, ça fait un moment depuis mon dernier article, mais je reviens tout juste d'une super conférence : la DjangoCon Europe. C'était ma première conférence virtuelle…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour, ça fait un moment depuis mon dernier article, mais je reviens tout juste
d'une super conférence : la DjangoCon Europe.&lt;/p&gt;
&lt;p&gt;C'était ma première conférence virtuelle. Grâce aux organisateurs et organisatrices, elle était
très bien organisée malgré les circonstances difficiles. Nous avions un
&lt;a class="reference external" href="https://gather.town/"&gt;gather.town&lt;/a&gt; pour rencontrer des gens, et les talks étaient hébergés sur
loudswarm, ce qui a très bien fonctionné ! C'était très intéressant. Il y a eu de super
talks et j'ai rencontré des personnes incroyables !&lt;/p&gt;
&lt;p&gt;Je suis aussi épuisée, lol. Je suppose que c'est une expérience différente de ce que j'imaginais,
d'après les retours des personnes qui l'ont vécue en présentiel. J'espère avoir
l'occasion d'assister à une autre édition en personne. Comme on dit, on vient pour
la syntaxe et on reste pour la communauté !&lt;/p&gt;
&lt;p&gt;J'ai donné mon premier lightning talk à la DjangoCon : « Run Django tests with
GitHub Actions », une petite introduction à GitHub Actions et à
son utilisation avec des services Docker. Ce genre de choses me rend très nerveuse,
mais je l'ai fait. Je suis contente d'avoir reçu des retours positifs. Je
sais aussi ce que je dois améliorer si je décide de retenter l'expérience
🙂&lt;/p&gt;
&lt;p&gt;Si vous avez un sujet en tête, lancez-vous. Vous ne le regretterez jamais et c'est une
belle expérience. Vous aiderez quelqu'un ou ferez découvrir à quelqu'un
quelque chose que vous n'auriez pas imaginé. Pour les sprints, c'était
compliqué pour moi de gérer les deux jours, mais j'ai pu être mentore
pour Django Girls le samedi. C'était une belle expérience pour moi.&lt;/p&gt;
</content><category term="blog"/><category term="django"/><category term="djangocon"/><category term="reflexion"/></entry><entry><title>Thoughts on DjangoCon Europe 2021</title><link href="https://sarahabd.com/blog/djangocon-europe-2021-thoughts" rel="alternate"/><published>2021-06-07T12:00:00+02:00</published><updated>2021-06-07T12:00:00+02:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2021-06-07:/blog/djangocon-europe-2021-thoughts</id><summary type="html">&lt;p class="first last"&gt;Hi there, it has been a while since my last post, but I' m now returning from a great conference: DjangoCon Europe. It was my first virtual…&lt;/p&gt;
</summary><content type="html">&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 class="reference external" 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;
</content><category term="blog"/><category term="django"/><category term="djangocon"/><category term="reflexion"/></entry><entry><title>Première contribution à l'open source, Hacktoberfest !</title><link href="https://sarahabd.com/fr/blog/first-contribution-hacktoberfest" rel="alternate"/><published>2020-11-03T09:08:00+01:00</published><updated>2020-11-03T09:08:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2020-11-03:/fr/blog/first-contribution-hacktoberfest</id><summary type="html">&lt;p class="first last"&gt;Première participation, première contribution à l'open source. Youpi ! Oui, j'ai terminé mon premier challenge Hacktoberfest, grâce à Digital Ocean…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Première participation, première contribution à l'open source. Youpi !&lt;/p&gt;
&lt;p&gt;Oui, j'ai terminé mon premier challenge Hacktoberfest, grâce à Digital
Ocean, Dev.to et Intel. Si vous ne voyez pas de quoi je parle, jetez un œil aux
&lt;a class="reference external" href="https://hacktoberfest.digitalocean.com/"&gt;détails de l'Hacktoberfest&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;J'ai toujours voulu contribuer à un projet open source. Mais il y avait
toujours des obstacles, mes premières pensées :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Quel projet choisir dans l'océan de dépôts
possibles ?&lt;/li&gt;
&lt;li&gt;Comment faire une bonne pull request pour un projet ?&lt;/li&gt;
&lt;li&gt;Les issues semblent souvent nécessiter une compréhension précise de la façon dont
les projets évoluent&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Oui, je sais ce que vous pensez : &lt;em&gt;elle est peut-être folle&lt;/em&gt;, ou peut-être simplement
&lt;em&gt;je ressens la même chose&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Je pense que c'est normal : chaque fois qu'on utilise un bon projet open
source, on a envie d'y contribuer un jour. L'open source, c'est
incroyable. Il y a tellement de projets utilisés par tellement de personnes.&lt;/p&gt;
&lt;p&gt;J'ai énormément de respect pour les mainteneurs et mainteneuses de projets open source, car beaucoup,
voire la plupart, de nos projets personnels ou professionnels échoueraient
sans eux.&lt;/p&gt;
&lt;p&gt;L'Hacktoberfest est l'une des meilleures façons de commencer à contribuer à des projets
open source. Leur site recense de nombreuses ressources et fournit
des informations pour contribuer, que vous soyez débutant·e ou
développeur·se confirmé·e. Et si vous suivez le CONTRIBUTING.md spécifique
du dépôt open source, vous ne pouvez pas vous perdre (normalement).&lt;/p&gt;
&lt;p&gt;N'hésitez pas à contacter les mainteneurs ou d'autres contributeurs pour
poser des questions si besoin, à regarder les labels, et à prendre le
temps de lire attentivement les issues.&lt;/p&gt;
&lt;p&gt;Si vous débutez, vous pouvez commencer par consulter ce lien qui
vous proposera de bonnes pistes pour démarrer :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://issuehub.io/?label%5B%5D=good+first+issue"&gt;issuehub.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Même si l'Hacktoberfest est terminée cette année, c'est toujours le bon
moment pour faire vos premières contributions.&lt;/p&gt;
&lt;p&gt;J'ai contribué à 2 projets :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/inspirezonetech/TeachMePythonLikeIm5"&gt;TeachMePythonLikeIm5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/inspirezonetech/TeachMeBashLikeIm5"&gt;TeachMeBashLikeIm5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C'était ma première Hacktoberfest et j'ai adoré cette expérience.
Je ne peux pas tout à fait l'expliquer, mais la satisfaction de contribuer
à quelque chose qui peut être utile à d'autres fait vraiment du bien. C'est aussi l'occasion
de découvrir d'autres projets, en cherchant ou grâce aux personnes qui partagent leurs
expériences, et d'apprendre de nouvelles choses, bien sûr.&lt;/p&gt;
&lt;p&gt;Je vais continuer à contribuer ❤️&lt;/p&gt;
&lt;p&gt;Malheureusement, je n'ai pas officiellement terminé le challenge Hacktoberfest
à cause d'un « &lt;a class="reference external" href="https://github.com/digitalocean/hacktoberfest/issues/724"&gt;comportement
voulu&lt;/a&gt; »
qui rend désormais certains dépôts non éligibles.&lt;/p&gt;
&lt;p&gt;Alors faites attention : si vous avez participé cette année et que vos PR sont
toujours en cours de revue, ce défaut peut encore vous arriver. &lt;a class="reference external" href="https://dev.to/funbeedev/check-your-hacktoberfest-profile-a-flaw-could-have-reversed-your-completion-of-the-challenge-without-you-knowing-it-2kg6"&gt;Fum
explique tout sur son blog&lt;/a&gt;.
Quoi qu'il en soit, c'est moins important que d'avoir enfin sauté le pas
et contribué à des projets open source, ce qui est vraiment
l'essence même de l'Hacktoberfest.&lt;/p&gt;
&lt;p&gt;À l'année prochaine, peut-être !&lt;/p&gt;
</content><category term="blog"/><category term="open-source"/><category term="hacktoberfest"/></entry><entry><title>First contribution to open source, hacktoberfest !</title><link href="https://sarahabd.com/blog/first-contribution-hacktoberfest" rel="alternate"/><published>2020-11-03T09:08:00+01:00</published><updated>2020-11-03T09:08:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2020-11-03:/blog/first-contribution-hacktoberfest</id><summary type="html">&lt;p class="first last"&gt;First participation, first contribution to open source. Yeah ! Yes, I finished my first the Hacktoberfest challenge, thanks to Digital Ocean…&lt;/p&gt;
</summary><content type="html">&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 class="reference external" href="https://hacktoberfest.digitalocean.com/"&gt;Hacktoberfest details&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 class="simple"&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;etc.&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 class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://issuehub.io/?label%5B%5D=good+first+issue"&gt;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 class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/inspirezonetech/TeachMePythonLikeIm5"&gt;TeachMePythonLikeIm5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/inspirezonetech/TeachMeBashLikeIm5"&gt;TeachMeBashLikeIm5&lt;/a&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 class="reference external" 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. &lt;a class="reference external" href="https://dev.to/funbeedev/check-your-hacktoberfest-profile-a-flaw-could-have-reversed-your-completion-of-the-challenge-without-you-knowing-it-2kg6"&gt;Fum
explain all in his blog&lt;/a&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;
&lt;p&gt;See you maybe next year!&lt;/p&gt;
</content><category term="blog"/><category term="open-source"/><category term="hacktoberfest"/></entry><entry><title>Déclencher manuellement GitHub Actions</title><link href="https://sarahabd.com/fr/blog/manual-trigger-with-github-actions" rel="alternate"/><published>2020-01-28T22:12:00+01:00</published><updated>2020-01-28T22:12:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2020-01-28:/fr/blog/manual-trigger-with-github-actions</id><summary type="html">&lt;p class="first last"&gt;Bonjour, cet article explique comment déclencher manuellement des builds GitHub Actions. Pourquoi vouloir faire ça ? Au lieu d'attendre…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Bonjour, cet article explique comment déclencher manuellement des builds
GitHub Actions.&lt;/p&gt;
&lt;div class="section" id="pourquoi-vouloir-faire-ca"&gt;
&lt;h2&gt;Pourquoi vouloir faire ça ?&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Au lieu d'attendre simplement un changement de code ou de workflow GitHub ?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Eh bien, par exemple, la dernière fois que votre build sur master s'est exécuté, certains
des serveurs utilisés par votre build étaient peut-être indisponibles (par exemple : le registre npm, une
API que vous utilisez pour les tests, etc.).&lt;/p&gt;
&lt;p&gt;Pour l'instant, &lt;a class="reference external" href="https://github.community/t5/GitHub-Actions/GitHub-Actions-Manual-Trigger-Approvals/td-p/31504"&gt;GitHub indique qu'il n'y a aucun moyen de déclencher manuellement un
build&lt;/a&gt;,
alors que la question a été &lt;a class="reference external" href="https://stackoverflow.com/q/58933155/7087644"&gt;posée sur
StackOverflow&lt;/a&gt; et que certaines
personnes utilisent même CURL pour déclencher des builds manuellement.&lt;/p&gt;
&lt;p&gt;Mais j'ai trouvé une meilleure solution ! Avec ma solution, une fois
en place, le bouton ⭐️ de votre dépôt GitHub déclenchera un build chaque
fois que VOUS (et seulement vous) mettrez une étoile au dépôt. Vous pouvez le faire autant
de fois que vous voulez.&lt;/p&gt;
&lt;p&gt;Oui, c'est une solution TRÈS &lt;em&gt;bricolée&lt;/em&gt;, mais elle fonctionne plutôt bien. ✨&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="comment-declencher-manuellement"&gt;
&lt;h2&gt;Comment déclencher manuellement&lt;/h2&gt;
&lt;p&gt;Entrons dans le vif du sujet.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="GIF montrant l'utilisation du bouton étoile pour déclencher manuellement un workflow" src="https://dev-to-uploads.s3.amazonaws.com/i/6oqnfhr50mczsodhp57c.gif" /&gt;
&lt;/div&gt;
&lt;p&gt;Le bouton ⭐️ sert à lancer le workflow quand c'est possible, comme ceci.&lt;/p&gt;
&lt;p&gt;Modifiez votre fichier de workflow pour y inclure :&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p-Indicator"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;started&lt;/span&gt;&lt;span class="p-Indicator"&gt;]&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Ainsi, le workflow sera exécuté chaque fois que vous mettrez une étoile au dépôt, ou que vous l'enlèverez
puis la remettrez.&lt;/p&gt;
&lt;p&gt;Si on combine ça avec &lt;a class="reference external" href="https://stackoverflow.com/a/58965362"&gt;un conseil utile de
Samira&lt;/a&gt; sur Stack Overflow, on
peut lancer le workflow uniquement si c'est le ou la propriétaire qui déclenche l'action.&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;github.actor == github.event.repository.owner.login&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Ça évite que l'action soit exécutée par d'autres personnes, et la réserve aux mainteneurs par
exemple.&lt;/p&gt;
&lt;p&gt;Ensuite, vous pouvez ajouter votre ou vos jobs et des services supplémentaires.&lt;/p&gt;
&lt;p&gt;Au final, on obtient le workflow suivant...&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Test&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p-Indicator"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;started&lt;/span&gt;&lt;span class="p-Indicator"&gt;]&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;github.actor == github.event.repository.owner.login&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Checkout repository&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/checkout&amp;#64;v2&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="c1"&gt;#  add more ...&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;C'est une base, vous pouvez donc l'adapter à un workflow existant ou en créer
un nouveau à partir de celle-ci.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="quelques-remarques"&gt;
&lt;h2&gt;Quelques remarques&lt;/h2&gt;
&lt;p&gt;Il est possible de &lt;strong&gt;combiner deux événements&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Par exemple, vous pouvez configurer votre workflow avec l'événement watch et à chaque
push, pour avoir les deux possibilités.&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Test&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;push&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;branches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;master&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p-Indicator"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;started&lt;/span&gt;&lt;span class="p-Indicator"&gt;]&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Ici, le processus s'exécute &lt;strong&gt;à chaque push sur la branche master et à chaque étoile sur
le dépôt&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;N'oubliez pas&lt;/strong&gt; que si vous voulez relancer un workflow qui a
échoué, vous pouvez relancer toutes les vérifications grâce à un bouton de l'interface prévu pour les
workflows en échec, comme ceci...&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="" src="https://thepracticaldev.s3.amazonaws.com/i/jm4zi3ccyfze9eyndk6g.png:alt:Captured'écrandel'ongletActionsaveclebouton«Re-runfailed»enhautàdroite" /&gt;
&lt;p class="caption"&gt;Capture d'écran de l'onglet Actions sur GitHub&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Tout dépend de ce que vous voulez vraiment faire.&lt;/p&gt;
&lt;p&gt;De plus, vous pouvez lancer tout le workflow avec l'événement watch, ou seulement
certaines étapes en ajoutant une condition if sur une étape, comme ceci :&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Test&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p-Indicator"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;started&lt;/span&gt;&lt;span class="p-Indicator"&gt;]&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Checkout repository&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/checkout&amp;#64;v2&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Step 2&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;github.actor == github.event.repository.owner.login&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Dans ce cas, l'étape 2 ne s'exécutera que si le dépôt reçoit une étoile de son
propriétaire.&lt;/p&gt;
&lt;blockquote&gt;
&lt;strong&gt;N'oubliez pas&lt;/strong&gt; que le bouton ⭐️ lance le workflow uniquement depuis la
branche par défaut (master).&lt;/blockquote&gt;
&lt;p&gt;Notez qu'il existe des permissions dans les paramètres du dépôt pour désactiver les actions
ou empêcher l'exécution d'actions tierces.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Capture d'écran des permissions des actions avec 3 options : « Enable local and third party Actions for this repository », « Enable local Actions only for this repository » et « Disable Action for this repository »" src="https://thepracticaldev.s3.amazonaws.com/i/r40qoujp9qt08tz9lmyo.png" /&gt;
&lt;p class="caption"&gt;Capture d'écran des permissions des actions dans les paramètres&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Mise à jour&lt;/strong&gt; : comme l'a suggéré &lt;a class="reference external" href="https://dev.to/neilime/comment/nipi"&gt;Emilien Escalle dans les commentaires sur
dev.to&lt;/a&gt;, on peut aussi configurer
le workflow uniquement pour les collaborateurs et collaboratrices, en créant un autre job dont
dépendra le build : il vérifie si la personne collabore au projet, sinon le workflow
échoue.&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;authorize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;octokit/request-action&amp;#64;v2.0.0&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nt"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;GET /repos/:repository/collaborators/${{ github.actor }}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nt"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;${{ github.repository }}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nt"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nt"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;needs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p-Indicator"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;authorize&lt;/span&gt;&lt;span class="p-Indicator"&gt;]&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="w-Error"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;...&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="bon-a-savoir"&gt;
&lt;h2&gt;Bon à savoir...&lt;/h2&gt;
&lt;p&gt;GitHub vient &lt;em&gt;tout juste&lt;/em&gt; de &lt;a class="reference external" href="https://github.blog/changelog/2020-01-27-github-actions-api-beta/"&gt;publier ses API
Actions&lt;/a&gt;,
ce qui devrait bientôt permettre à GitHub ou à des extensions de navigateur d'ajouter
des boutons « déclencher le workflow » dans leur interface.&lt;/p&gt;
&lt;p&gt;J'espère que cet article vous a plu, et un merci tout particulier à
&lt;a class="reference external" href="https://dev.to/vvo"&gt;Vincent&lt;/a&gt; qui m'a poussée à l'écrire :)&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="github-actions"/><category term="howto"/><category term="testing"/></entry><entry><title>Manual trigger with Github Actions</title><link href="https://sarahabd.com/blog/manual-trigger-with-github-actions" rel="alternate"/><published>2020-01-28T22:12:00+01:00</published><updated>2020-01-28T22:12:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2020-01-28:/blog/manual-trigger-with-github-actions</id><summary type="html">&lt;p class="first last"&gt;Hi there, this blog post explains how to manually trigger builds of GitHub actions. Why would you want to do that? Instead of just waiting…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Hi there, this blog post explains how to manually trigger builds of
GitHub actions.&lt;/p&gt;
&lt;div class="section" id="why-would-you-want-to-do-that"&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;&lt;/p&gt;
&lt;p&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 class="reference external" 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 class="reference external" 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. 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;/div&gt;
&lt;div class="section" id="how-to-do-manual-trigger"&gt;
&lt;h2&gt;How to do manual trigger&lt;/h2&gt;
&lt;p&gt;Let’s dig into it.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="GIF image that show the use of the star button to trigger manually a workflow" src="https://dev-to-uploads.s3.amazonaws.com/i/6oqnfhr50mczsodhp57c.gif" /&gt;
&lt;/div&gt;
&lt;p&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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p-Indicator"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;started&lt;/span&gt;&lt;span class="p-Indicator"&gt;]&lt;/span&gt;
&lt;/pre&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 class="reference external" 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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;github.actor == github.event.repository.owner.login&lt;/span&gt;
&lt;/pre&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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Test&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p-Indicator"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;started&lt;/span&gt;&lt;span class="p-Indicator"&gt;]&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;github.actor == github.event.repository.owner.login&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Checkout repository&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/checkout&amp;#64;v2&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="c1"&gt;#  add more ...&lt;/span&gt;
&lt;/pre&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;/div&gt;
&lt;div class="section" id="few-notes"&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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Test&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;push&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;branches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;master&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p-Indicator"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;started&lt;/span&gt;&lt;span class="p-Indicator"&gt;]&lt;/span&gt;
&lt;/pre&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, you can re-run all the checks with a UI button set for a failed
workflow just like that…&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="" src="https://thepracticaldev.s3.amazonaws.com/i/jm4zi3ccyfze9eyndk6g.png:alt:Screenshotoftheactionstabwiththebuttonre-runfailedonthetoprightcorner" /&gt;
&lt;p class="caption"&gt;Screenshot of the actions tab on GitHub&lt;/p&gt;
&lt;/div&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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Test&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p-Indicator"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;started&lt;/span&gt;&lt;span class="p-Indicator"&gt;]&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Checkout repository&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/checkout&amp;#64;v2&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Step 2&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;github.actor == github.event.repository.owner.login&lt;/span&gt;
&lt;/pre&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;strong&gt;Don’t forget&lt;/strong&gt; that the ⭐️ button launch the workflow from the
default branch (master) only.&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;div class="figure"&gt;
&lt;img alt="Screenshot of action permissions with 3 options: &amp;quot;Enable local and third party Actions for this repository&amp;quot;, &amp;quot;Enable local Actions only for this repository&amp;quot; and &amp;quot;Disable Action for this repository&amp;quot;" src="https://thepracticaldev.s3.amazonaws.com/i/r40qoujp9qt08tz9lmyo.png" /&gt;
&lt;p class="caption"&gt;Screenshot of the actions permissions in the settings&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Suggested by &lt;a class="reference external" href="https://dev.to/neilime/comment/nipi"&gt;Emilien Escalle in comments on
dev.to&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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;authorize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;octokit/request-action&amp;#64;v2.0.0&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nt"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;GET /repos/:repository/collaborators/${{ github.actor }}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nt"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;${{ github.repository }}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nt"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nt"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;needs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p-Indicator"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;authorize&lt;/span&gt;&lt;span class="p-Indicator"&gt;]&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="w-Error"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;...&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="good-to-know"&gt;
&lt;h2&gt;Good to know…&lt;/h2&gt;
&lt;p&gt;GitHub &lt;em&gt;just&lt;/em&gt; &lt;a class="reference external" 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;I hope you liked this post and special thanks to
&lt;a class="reference external" href="https://dev.to/vvo"&gt;Vincent&lt;/a&gt; who pushed me to write it :)&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="github-actions"/><category term="howto"/><category term="testing"/></entry><entry><title>La relation entre dev confirmé·e/senior et dev junior</title><link href="https://sarahabd.com/fr/blog/relation-between-senior-and-junior-dev" rel="alternate"/><published>2020-01-01T22:12:00+01:00</published><updated>2020-01-01T22:12:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2020-01-01:/fr/blog/relation-between-senior-and-junior-dev</id><summary type="html">&lt;p class="first last"&gt;J'ai été formatrice et aussi apprenante, alors j'ai quelque chose à vous dire. J'ai entendu tellement de remarques comme « tu es trop junior », « tu n'es…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;J'ai été formatrice et aussi apprenante, alors j'ai quelque chose à vous
dire.&lt;/p&gt;
&lt;p&gt;J'ai entendu tellement de remarques comme &lt;em&gt;« tu es trop junior »&lt;/em&gt;, &lt;em&gt;« tu n'es pas
dev confirmée/senior »&lt;/em&gt;. Je suis sûre que vous les avez entendues aussi.&lt;/p&gt;
&lt;p&gt;Si vous me dites que quelque chose est impossible, je suis le genre de femme qui
va essayer de réussir même s'il n'y a qu'une petite chance.&lt;/p&gt;
&lt;p&gt;Oui, j'ai essayé d'atteindre un niveau technique proche de celui
des développeurs et développeuses qui m'ont inspirée, malgré mon expérience limitée.&lt;/p&gt;
&lt;p&gt;Le fait est que certaines personnes pensent qu'un·e junior doit écouter les
devs confirmé·es/seniors, et c'est tout.&lt;/p&gt;
&lt;p&gt;Le ou la dev confirmé·e/senior est très qualifié·e et a de l'expérience. C'est certain.&lt;/p&gt;
&lt;blockquote&gt;
Mais ça reste &lt;strong&gt;un échange&lt;/strong&gt;.&lt;/blockquote&gt;
&lt;p&gt;Partager ses connaissances n'est pas facile pour tout le monde. Et quand on est dans cette
situation, on doit parfois expliquer des choses complexes avec
des mots simples et rendre des idées abstraites plus digestes.&lt;/p&gt;
&lt;p&gt;C'est un art, pas une science, vraiment.&lt;/p&gt;
&lt;p&gt;On sait tous qu'&lt;strong&gt;un·e développeur·se apprend en permanence&lt;/strong&gt;, y compris en posant des questions
à d'autres devs. Parfois, les devs posent des questions auxquelles on n'avait pas pensé, ou
dont on ne connaît simplement pas la réponse, et on a envie de la connaître aussi. Alors
parfois, leur question nous pousse à faire plus de recherches et nous aide à élargir
nos connaissances.&lt;/p&gt;
&lt;div class="section" id="a-toi-dev-junior"&gt;
&lt;h2&gt;À toi, dev junior&lt;/h2&gt;
&lt;p&gt;Ne pense pas que le ou la dev expérimenté·e n'a pas de temps pour toi. S'il ou elle est
vraiment occupé·e, ajoute une réunion dans son agenda. Ça montrera que c'est
important pour toi et que tu as vraiment besoin de ce point. Ça peut être le moment de
clarifier ce qui est bien dans ton travail et ce qui doit être amélioré.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Essaie de trouver la réponse avant de demander, mais n'y consacre pas trop de temps&lt;/strong&gt;.
Si tu es bloqué·e, demande de l'aide. Tu perds du temps : même s'il
semble important de t'en sortir seul·e et d'en retirer la gloire, tu aurais pu
faire tellement plus. Et quand c'est résolu en deux secondes, il vaut bien mieux
ne pas avoir attendu aussi longtemps pour demander de l'aide 😉&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-toi-dev-confirmee-senior"&gt;
&lt;h2&gt;À toi, dev confirmé·e/senior&lt;/h2&gt;
&lt;p&gt;Certaines personnes t'admirent en secret, vraiment. Prends le temps d'aider
les devs juniors à progresser si tu en as la possibilité. C'est aussi l'occasion
de te challenger et de mieux connaître ton équipe.&lt;/p&gt;
&lt;p&gt;De mon point de vue, un·e excellent·e dev confirmé·e/senior n'est pas seulement quelqu'un de
compétent techniquement, c'est aussi quelqu'un qui aide les autres à progresser.
Un·e dev expérimenté·e devrait &lt;strong&gt;constamment apprendre à transmettre avec plus de
clarté, à mieux organiser son équipe et à communiquer plus
efficacement&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Et vous, qu'en pensez-vous ?&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="reflexion"/></entry><entry><title>Relation between middle/senior and junior dev</title><link href="https://sarahabd.com/blog/relation-between-senior-and-junior-dev" rel="alternate"/><published>2020-01-01T22:12:00+01:00</published><updated>2020-01-01T22:12:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2020-01-01:/blog/relation-between-senior-and-junior-dev</id><summary type="html">&lt;p class="first last"&gt;I've been a teacher and also a learner, so I've got something to tell you. I've heard so many comments like &amp;quot;you're too junior&amp;quot; , &amp;quot;you're…&lt;/p&gt;
</summary><content type="html">&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;
But it’s still &lt;strong&gt;an exchange&lt;/strong&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;div class="section" id="to-you-the-junior-dev"&gt;
&lt;h2&gt;To you the junior dev&lt;/h2&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;/div&gt;
&lt;div class="section" id="to-you-the-middle-senior-dev"&gt;
&lt;h2&gt;To you the middle/senior dev&lt;/h2&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;
&lt;/div&gt;
</content><category term="blog"/><category term="reflexion"/></entry><entry><title>Les services Docker dans GitHub Actions n'auront plus de secrets pour vous</title><link href="https://sarahabd.com/fr/blog/docker-services-in-github-actions" rel="alternate"/><published>2019-11-17T22:12:00+01:00</published><updated>2019-11-17T22:12:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2019-11-17:/fr/blog/docker-services-in-github-actions</id><summary type="html">&lt;p class="first last"&gt;J'explique plus en détail comment une action est structurée et comment utiliser les services Docker dans un article, mais ici je vais me concentrer sur les services…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;J'explique plus en détail &lt;a class="reference external" href="/fr/blog/create-github-actions-with-docker-services"&gt;comment une action est structurée et comment utiliser les services
Docker dans un
article&lt;/a&gt;, mais ici je vais
me concentrer davantage sur les services.&lt;/p&gt;
&lt;p&gt;Eh oui, la bonne nouvelle, c'est qu'on peut utiliser des conteneurs Docker comme services dans
GitHub Actions. 🎉&lt;/p&gt;
&lt;div class="section" id="comment-fait-on"&gt;
&lt;h2&gt;Comment fait-on ?&lt;/h2&gt;
&lt;p&gt;C'est très simple, c'est similaire à la définition d'un service dans un
&lt;em&gt;docker-compose.yml&lt;/em&gt;, mais avec beaucoup moins de paramètres.&lt;/p&gt;
&lt;p&gt;On utilise le mot-clé &lt;strong&gt;services&lt;/strong&gt; avec :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;la définition de l'image Docker à utiliser&lt;/li&gt;
&lt;li&gt;la liste des ports du service à exposer&lt;/li&gt;
&lt;li&gt;une liste de variables d'environnement&lt;/li&gt;
&lt;li&gt;une liste de volumes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tous ces éléments ne sont pas obligatoires, mais c'est bon à savoir.&lt;/p&gt;
&lt;p&gt;Concrètement, ça ressemble à ceci, pour un service Postgres :&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;env&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_BD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;5432/tcp&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Exemple réalisé par Chris Patterson et &lt;a class="reference external" href="https://dev.to/mscccc"&gt;Mike
Coutermarsh&lt;/a&gt; pour PostgreSQL. Vous pouvez trouver
l'exemple complet avec node juste
&lt;a class="reference external" href="https://github.com/actions/example-services"&gt;ici&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Il nous faut l'image Docker à lancer, le port à exposer et le nom du
service. Il est possible de transmettre des variables d'environnement ou des options
Docker, comme dans l'exemple ci-dessus. Les valeurs sensibles peuvent être définies
avec une &lt;a class="reference external" 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;clé
secrète&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="exemple-complet"&gt;
&lt;h2&gt;Exemple complet&lt;/h2&gt;
&lt;p&gt;Par exemple, on veut créer une action qui lance les tests de notre application
Django à chaque événement push.&lt;/p&gt;
&lt;p&gt;Le workflow suivant est mis en place :&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Test Workflow&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;push&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;tests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;

   &lt;/span&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_BD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;5432:5432&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5&lt;/span&gt;&lt;span class="w"&gt;

   &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/checkout&amp;#64;v1&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Set up Python 3.5.7&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/setup-python&amp;#64;v1&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nt"&gt;python-version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;3.5.7&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Install dependencies&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;pip install -r requirements.txt&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Run tests&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;python manage.py test&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Ici, le job tests consiste à :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;installer Python 3.5.7 sur l'environnement Ubuntu&lt;/li&gt;
&lt;li&gt;installer les dépendances&lt;/li&gt;
&lt;li&gt;lancer les tests avec la base de données Postgres&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dans cet exemple, il faut quand même surcharger les valeurs du service dans le
settings.py de Django pour la connexion à la base de données PostgreSQL, comme
ceci :&lt;/p&gt;
&lt;pre class="code python literal-block"&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="w"&gt;
&lt;/span&gt;    &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;       &lt;span class="s1"&gt;'ENGINE'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'django.db.backends.postgresql'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;       &lt;span class="s1"&gt;'NAME'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'postgres'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;       &lt;span class="s1"&gt;'USER'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'postgres'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;       &lt;span class="s1"&gt;'HOST'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'localhost'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;       &lt;span class="s1"&gt;'PORT'&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="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;/pre&gt;
&lt;p&gt;Si vous avez plusieurs configurations de base de données, vous pouvez utiliser une variable d'environnement
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;os.environ.get('HOST_NAME')&lt;/span&gt;&lt;/tt&gt; ou une configuration conditionnelle avec
&lt;tt class="docutils literal"&gt;if &lt;span class="pre"&gt;os.environ.get('GITHUB_WORKFLOW')&lt;/span&gt;&lt;/tt&gt; par exemple.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="quelques-remarques"&gt;
&lt;h2&gt;Quelques remarques&lt;/h2&gt;
&lt;p&gt;Il est parfois nécessaire d'attendre un retour sur l'état du service pour
établir une connexion. On définit donc un élément qui vérifie
l'état de santé du service pour savoir quand il est opérationnel (on parle aussi de
&lt;em&gt;health check&lt;/em&gt;).&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Celui-ci est pour Postgres, mais vous en trouverez pour plein d'autres, comme
Elasticsearch, MySQL, etc. Si vous n'avez pas de &lt;strong&gt;health
check&lt;/strong&gt; disponible, on met en pause l'exécution avec la commande
sleep. Oui, ce n'est pas terrible, je vous l'accorde...&lt;/p&gt;
&lt;p&gt;Pour relier le service au job du workflow, il faut l'&lt;strong&gt;hôte&lt;/strong&gt;.
Si votre workflow s'exécute :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;dans la machine virtuelle&lt;/em&gt;, ce sera &lt;strong&gt;localhost&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;dans un conteneur&lt;/em&gt;, ce sera &lt;strong&gt;le nom du service&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;N'oubliez pas&lt;/strong&gt;, vous ne pouvez utiliser les services Docker qu'avec une
distribution Linux.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour le port, voici comment y accéder dans votre ou vos jobs :&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="l-Scalar-Plain"&gt;${{ job.services.postgres.ports[5432] }}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Dans le premier exemple, un port libre de la machine est attribué aléatoirement au port 5432
et c'est par lui qu'on y accède.&lt;/p&gt;
&lt;p&gt;Néanmoins, on peut aussi l'attribuer de manière fixe :&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;5432:5432&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Ici, le port 5432 du service est relié au port 5432 de
la machine définie dans l'action.&lt;/p&gt;
&lt;p&gt;Et voilà, vous êtes prêt·e à utiliser des services dans votre workflow ! 💪&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="github-actions"/><category term="docker"/><category term="postgresql"/><category term="testing"/></entry><entry><title>Docker services in Github Actions won't have secrets for you</title><link href="https://sarahabd.com/blog/docker-services-in-github-actions" rel="alternate"/><published>2019-11-17T22:12:00+01:00</published><updated>2019-11-17T22:12:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2019-11-17:/blog/docker-services-in-github-actions</id><summary type="html">&lt;p class="first last"&gt;I explain deeper how is structured an action and how to use docker services in an article but I will focus here more on services. Yeah…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;I explain deeper &lt;a class="reference external" href="/blog/create-github-actions-with-docker-services"&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;div class="section" id="how-do-we-do-it"&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 class="simple"&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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;env&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_BD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;5432/tcp&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Example made by Chris Patterson and &lt;a class="reference external" href="https://dev.to/mscccc"&gt;Mike
Coutermarsh&lt;/a&gt; for PostgreSQL. You can find the
full example with node just
&lt;a class="reference external" 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 class="reference external" 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;/div&gt;
&lt;div class="section" id="full-example"&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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Test Workflow&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;push&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;tests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;

   &lt;/span&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_BD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;5432:5432&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5&lt;/span&gt;&lt;span class="w"&gt;

   &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/checkout&amp;#64;v1&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Set up Python 3.5.7&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/setup-python&amp;#64;v1&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nt"&gt;python-version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;3.5.7&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Install dependencies&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;pip install -r requirements.txt&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Run tests&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;python manage.py test&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Here the job tests consist of:&lt;/p&gt;
&lt;ul class="simple"&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;/p&gt;
&lt;pre class="code python literal-block"&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="w"&gt;
&lt;/span&gt;    &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;       &lt;span class="s1"&gt;'ENGINE'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'django.db.backends.postgresql'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;       &lt;span class="s1"&gt;'NAME'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'postgres'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;       &lt;span class="s1"&gt;'USER'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'postgres'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;       &lt;span class="s1"&gt;'HOST'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'localhost'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;       &lt;span class="s1"&gt;'PORT'&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="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;/pre&gt;
&lt;p&gt;If you have multiple settings for database, you can do with env variable
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;os.environ.get('HOST_NAME')&lt;/span&gt;&lt;/tt&gt; or a conditional settings with
&lt;tt class="docutils literal"&gt;if &lt;span class="pre"&gt;os.environ.get('GITHUB_WORKFLOW')&lt;/span&gt;&lt;/tt&gt; for example.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="few-notes"&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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;This one is for postgres but you can find multiple such as
elasticsearch, mysql and so on… 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. In case you’re running your workflow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;in the virtual machine&lt;/em&gt;, it will be &lt;strong&gt;localhost&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&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;/p&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;/li&gt;
&lt;/ul&gt;
&lt;p&gt;According to the port, to access it on your job(s), it will be like
that:&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="l-Scalar-Plain"&gt;${{ job.services.postgres.ports[5432] }}&lt;/span&gt;
&lt;/pre&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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;5432:5432&lt;/span&gt;
&lt;/pre&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;
&lt;/div&gt;
</content><category term="blog"/><category term="github-actions"/><category term="docker"/><category term="postgresql"/><category term="testing"/></entry><entry><title>Comment créer une GitHub Action pour lancer des tests avec des services ?</title><link href="https://sarahabd.com/fr/blog/create-github-actions-with-docker-services" rel="alternate"/><published>2019-11-05T22:12:00+01:00</published><updated>2019-11-05T22:12:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2019-11-05:/fr/blog/create-github-actions-with-docker-services</id><summary type="html">&lt;p class="first last"&gt;Je creuse GitHub Actions depuis que j'ai eu accès à la bêta. GitHub Actions est disponible pour tout le monde depuis le 11 novembre 2019 et je…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Je creuse GitHub Actions depuis que j'ai eu accès à la bêta.
GitHub Actions est disponible pour tout le monde depuis le 11 novembre 2019, et je peux
vous l'expliquer. 🎉&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://tkt.paris/comment-creer-une-action-github-pour-tester-son-application-avec-des-services"&gt;Une autre version française de l'article&lt;/a&gt; est
disponible ici.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Photo de l'arborescence d'un projet avec les commits et un graphe Git à trois branches" src="https://cdn-images-1.medium.com/max/1024/0*dcmLNHncSQ4306nX" /&gt;
&lt;p class="caption"&gt;Photo de Yancy Min sur Unsplash&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="qu-est-ce-que-c-est"&gt;
&lt;h2&gt;Qu'est-ce que c'est ?&lt;/h2&gt;
&lt;p&gt;GitHub Actions est une solution d'intégration continue et de déploiement
continu (CI/CD). C'est une nouvelle fonctionnalité de GitHub, qui s'affiche
sous forme d'onglet dans votre dépôt. Ses opérations sont déclenchées par des &lt;strong&gt;événements
Git, comme le push d'un commit&lt;/strong&gt;. Pour créer une nouvelle séquence
d'événements à exécuter lors d'un push, il faut créer un ensemble de commandes
qui seront exécutées selon les spécificités du
projet. Une fois mis en place, ce service est conçu pour exécuter des processus automatiquement et
en continu pour le travail collaboratif sur un dépôt Git. Il
faut noter que GitHub Actions repose sur Docker, il est donc
recommandé d'avoir quelques connaissances à ce sujet pour l'utiliser.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="ecrire-son-action"&gt;
&lt;h2&gt;Écrire son action&lt;/h2&gt;
&lt;p&gt;Une action contient plusieurs éléments nécessaires à l'exécution d'un processus : l'événement
&lt;strong&gt;on&lt;/strong&gt;, qui correspond à l'événement GitHub : push, pull request,
etc. Pendant la bêta, seuls les déclencheurs push et pull request
sont disponibles.&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p-Indicator"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="p-Indicator"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="p-Indicator"&gt;]&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Il est bien sûr possible de définir la portée de votre action, pour qu'elle effectue
des tâches précises sur certaines branches de votre dépôt, mais pas sur d'autres.
Par exemple, un déploiement automatique sur un serveur depuis la
branche staging, mais pas depuis la branche dev.&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;push&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;branches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;staging&lt;/span&gt;
&lt;/pre&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;Ensuite, il y a les &lt;strong&gt;jobs&lt;/strong&gt;. En pratique, un job est une série d'étapes
exécutées dans l'ordre. Il a 2 éléments importants : l'environnement
et les étapes que le service doit réaliser.&lt;/div&gt;
&lt;div class="line"&gt;Le paramètre &lt;strong&gt;runs-on&lt;/strong&gt; définit l'environnement dans lequel l'action
est exécutée :&lt;/div&gt;
&lt;/div&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Il existe plusieurs environnements virtuels possibles pour l'exécution de
votre action, ce qui peut être utile pour correspondre aux
spécificités de chacun. D'Ubuntu 19.10 à Windows 2016, vous avez
le choix 😉&lt;/p&gt;
&lt;blockquote&gt;
Il faut noter que chaque job est exécuté dans une nouvelle instance de
l'environnement virtuel.&lt;/blockquote&gt;
&lt;p&gt;Donc, si vous voulez effectuer une série d'actions liées entre elles,
il vaut peut-être mieux le faire dans le même job. Mais il est possible de
créer des dépendances entre jobs avec le paramètre &lt;strong&gt;need&lt;/strong&gt; :&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;job1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;job2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;need&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;job1&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Dans ce cas, job2 ne s'exécutera qu'une fois job1 terminé.&lt;/p&gt;
&lt;p&gt;Ensuite, il y a toutes les étapes à réaliser pendant le processus. Dans une optique
d'intégration continue, le but est de lancer les tests automatiquement.
Mais un certain nombre d'éléments doivent être définis avant de pouvoir
lancer les tests !&lt;/p&gt;
&lt;p&gt;Cet ensemble est défini par le mot-clé &lt;strong&gt;steps&lt;/strong&gt;. Chaque étape nécessite au
moins un élément à exécuter, c'est-à-dire l'un des éléments suivants :&lt;/p&gt;
&lt;p&gt;le mot-clé &lt;strong&gt;uses&lt;/strong&gt;, pour utiliser un élément précis :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;une action publique&lt;/li&gt;
&lt;li&gt;une action dans le même dépôt&lt;/li&gt;
&lt;li&gt;une action sur le Docker Hub ou sur le registre public Docker&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ou&lt;/p&gt;
&lt;p&gt;le mot-clé &lt;strong&gt;run&lt;/strong&gt;, pour lancer une commande en bash (sachant qu'il existe
plusieurs façons d'exécuter une commande si nécessaire)&lt;/p&gt;
&lt;p&gt;Enfin, on associe le paramètre &lt;strong&gt;name&lt;/strong&gt; pour savoir quelle étape il
représente. Un exemple étant toujours plus parlant, voici un job pour
tester un projet Django :&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;tests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;

   &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/checkout&amp;#64;v1&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Set up Python 3.5.7&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/setup-python&amp;#64;v1&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nt"&gt;python-version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;3.5.7&lt;/span&gt;&lt;span class="w"&gt;

   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Install dependencies&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;pip install -r requirements.txt&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Run tests&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;python manage.py test&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Ici, le job tests consiste à :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;installer Python 3.5.7 sur l'environnement Ubuntu&lt;/li&gt;
&lt;li&gt;installer les dépendances&lt;/li&gt;
&lt;li&gt;lancer les tests&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour tester en conditions réelles, il faut une base de données, d'où la
&lt;em&gt;mise en place de services&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="ajouter-un-service-a-son-action"&gt;
&lt;h2&gt;Ajouter un service à son action&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Comment fait-on ?&lt;/em&gt; C'est très simple, c'est similaire à la définition d'un
service dans un docker-compose.yml, mais avec beaucoup moins de paramètres.&lt;/p&gt;
&lt;p&gt;On utilise le mot-clé &lt;strong&gt;services&lt;/strong&gt; avec :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;la définition de l'image Docker à utiliser&lt;/li&gt;
&lt;li&gt;la liste des ports du service à exposer&lt;/li&gt;
&lt;li&gt;une liste de variables d'environnement&lt;/li&gt;
&lt;li&gt;une liste de volumes&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;Tous ces éléments ne sont pas obligatoires, mais c'est bon à savoir.&lt;/div&gt;
&lt;div class="line"&gt;Concrètement, ça ressemble à ceci, pour un service Postgres :&lt;/div&gt;
&lt;/div&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;env&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_BD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;5432/tcp&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Il nous faut l'image Docker à lancer, le port à exposer et le nom du
service. Il est possible de transmettre des variables d'environnement ou des options
Docker, comme dans l'exemple ci-dessus. Les valeurs sensibles peuvent être définies
avec une &lt;a class="reference external" 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;clé
secrète&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;De plus, il est parfois nécessaire d'attendre un retour sur l'état du service
pour établir une connexion. On définit donc un élément
qui vérifie l'état de santé du service pour savoir quand il est opérationnel
(on parle aussi de health check). J'ai repris l'exemple réalisé par Chris
Patterson et &lt;a class="reference external" href="https://dev.to/mscccc"&gt;Mike Coutermarsh&lt;/a&gt; pour
PostgreSQL.&lt;/p&gt;
&lt;p&gt;Si vous n'avez pas de health check disponible, on met en pause l'exécution
du processus avec la commande &lt;strong&gt;sleep&lt;/strong&gt;. Oui, ce n'est pas terrible, je vous l'accorde...&lt;/p&gt;
&lt;p&gt;Tout ça, c'est très bien, mais il faut faire le lien entre le service
et notre application. On le fera via le port, et pour l'hôte, ce
sera &lt;em&gt;localhost&lt;/em&gt;, puisque le service est exécuté directement dans la machine
Ubuntu dans notre exemple. Sinon, ça aurait été le nom du
service.&lt;/p&gt;
&lt;p&gt;Dans l'exemple précédent, un port libre de la machine est attribué aléatoirement au port 5432,
et on y accède comme ceci :&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="l-Scalar-Plain"&gt;${{ job.services.postgres.ports[5432] }}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Néanmoins, on peut aussi l'attribuer de manière fixe :&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;5432:5432&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Ici, le port 5432 du service est relié au port 5432 de
la machine définie dans l'action.&lt;/p&gt;
&lt;p&gt;Le workflow suivant est mis en place :&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Test Workflow&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;push&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;tests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;

   &lt;/span&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_BD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;5432:5432&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5&lt;/span&gt;&lt;span class="w"&gt;

   &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/checkout&amp;#64;v1&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Set up Python 3.5.7&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/setup-python&amp;#64;v1&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nt"&gt;python-version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;3.5.7&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Install dependencies&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;pip install -r requirements.txt&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Run tests&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;python manage.py test&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Dans notre exemple, il faut quand même surcharger les valeurs du service dans le
settings.py de Django pour la connexion à la base de données PostgreSQL.&lt;/p&gt;
&lt;p&gt;Et le tour est joué, il ne reste plus qu'à pousser du code et espérer que ça marche. 😉&lt;/p&gt;
&lt;/div&gt;
</content><category term="blog"/><category term="github-actions"/><category term="testing"/><category term="docker"/><category term="howto"/><category term="django"/></entry><entry><title>How to create Github Actions to run tests with services ?</title><link href="https://sarahabd.com/blog/create-github-actions-with-docker-services" rel="alternate"/><published>2019-11-05T22:12:00+01:00</published><updated>2019-11-05T22:12:00+01:00</updated><author><name>Sarah Abderemane</name></author><id>tag:sarahabd.com,2019-11-05:/blog/create-github-actions-with-docker-services</id><summary type="html">&lt;p class="first last"&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…&lt;/p&gt;
</summary><content type="html">&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;&lt;a class="reference external" href="https://tkt.paris/comment-creer-une-action-github-pour-tester-son-application-avec-des-services"&gt;French version of the article&lt;/a&gt;  right
here.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Photo of tree of a project with the commits and a graph Git with three branches" src="https://cdn-images-1.medium.com/max/1024/0*dcmLNHncSQ4306nX" /&gt;
&lt;p class="caption"&gt;Photo by Yancy Min on Unsplash&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-is-it"&gt;
&lt;h2&gt;What is it ?&lt;/h2&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;/div&gt;
&lt;div class="section" id="write-your-action"&gt;
&lt;h2&gt;Write your action&lt;/h2&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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p-Indicator"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="p-Indicator"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="p-Indicator"&gt;]&lt;/span&gt;
&lt;/pre&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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;push&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;branches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;staging&lt;/span&gt;
&lt;/pre&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&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;/div&gt;
&lt;div class="line"&gt;The &lt;strong&gt;runs-on&lt;/strong&gt; parameter defines the environment in which the action
is performed:&lt;/div&gt;
&lt;/div&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;
&lt;/pre&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;
It should be noted that each job is performed in a new instance of
the virtual environment.&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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;job1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;job2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;need&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;job1&lt;/span&gt;
&lt;/pre&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.&amp;nbsp;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 class="simple"&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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;tests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;

   &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/checkout&amp;#64;v1&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Set up Python 3.5.7&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/setup-python&amp;#64;v1&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nt"&gt;python-version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;3.5.7&lt;/span&gt;&lt;span class="w"&gt;

   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Install dependencies&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;pip install -r requirements.txt&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Run tests&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;python manage.py test&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Here the job tests consist of:&lt;/p&gt;
&lt;ul class="simple"&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;/div&gt;
&lt;div class="section" id="add-a-service-to-your-action"&gt;
&lt;h2&gt;Add a service to your action&lt;/h2&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 class="simple"&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;div class="line-block"&gt;
&lt;div class="line"&gt;Not all of these elements are required but good to know.&lt;/div&gt;
&lt;div class="line"&gt;In concrete terms, it looks like this, for a Postgres service:&lt;/div&gt;
&lt;/div&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;env&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_BD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;5432/tcp&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5&lt;/span&gt;
&lt;/pre&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 class="reference external" 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 class="reference external" 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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="l-Scalar-Plain"&gt;${{ job.services.postgres.ports[5432] }}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Nevertheless, it can be assigned in a fixed way:&lt;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;5432:5432&lt;/span&gt;
&lt;/pre&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;/p&gt;
&lt;pre class="code yaml literal-block"&gt;
&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Test Workflow&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;push&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nt"&gt;tests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;

   &lt;/span&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;POSTGRES_BD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;postgres&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;5432:5432&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5&lt;/span&gt;&lt;span class="w"&gt;

   &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/checkout&amp;#64;v1&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Set up Python 3.5.7&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;actions/setup-python&amp;#64;v1&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nt"&gt;python-version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;3.5.7&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Install dependencies&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;pip install -r requirements.txt&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;Run tests&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l-Scalar-Plain"&gt;python manage.py test&lt;/span&gt;
&lt;/pre&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;/div&gt;
</content><category term="blog"/><category term="github-actions"/><category term="testing"/><category term="docker"/><category term="howto"/><category term="django"/></entry></feed>