Comment utiliser Bencher dans GitHub Actions
Depending on your use case, you can set up Continuous Benchmarking in GitHub Actions for your:
Assurez-vous dâavoir crĂ©Ă© un jeton API
et de lâavoir dĂ©fini comme un secret de RĂ©fĂ©rentiel nommĂ© BENCHER_API_TOKEN
avant de continuer !
Allez à Votre Répo -> ParamÚtres -> Secrets et variables -> Actions -> Nouveau secret de référentiel
.
Nommez le secret BENCHER_API_TOKEN
et définissez la valeur secrÚte sur votre jeton API.
Dans GitHub Actions,
les secrets ne sont pas transmis au runner lorsquâun workflow est dĂ©clenchĂ© depuis un dĂ©pĂŽt forkĂ©.
Par consĂ©quent, vous devrez utiliser une branche du mĂȘme dĂ©pĂŽt
lors de lâajout de lâun des workflows ci-dessous Ă votre dĂ©pĂŽt avec une pull request.
Si vous essayez dâajouter Bencher avec une pull request Ă partir dâun fork,
alors le secret BENCHER_API_TOKEN
ne sera pas disponible.
${{ secrets.BENCHER_API_TOKEN }}
sera une chaĂźne vide.
Branche de Base
Un pilier du Benchmarking Statistique Continu est dâavoir une base de rĂ©fĂ©rence historique pour votre branche de base. Cette base de rĂ©fĂ©rence historique peut alors ĂȘtre utilisĂ©e pour dĂ©tecter les rĂ©gressions de performance dans les Pull Requests.
- Créez un fichier
workflow
GitHub Actions. (ex:.github/workflows/base_benchmarks.yml
) - Exécutez sur les événements
push
vers la branchemain
. Consultez la documentation GitHub Actionson
et la documentation GitHub Actionspush
pour un aperçu complet. (ex:on: push: branches: main
) - Créez un
job
GitHub Actions. (ex:jobs: benchmark_base_branch
) - DĂ©finissez les autorisations pour le
GITHUB_TOKEN
surwrite
pourchecks
. (ex :permissions: checks: write
) - Définissez le type de machine sur laquelle le job sera exécuté.
Consultez la documentation GitHub Actions
runs-on
pour un aperçu complet. (ex:runs-on: ubuntu-latest
) - Récupérez le code source de votre branche de base.
(ex:
uses: actions/checkout@v4
) - Installez le Bencher CLI en utilisant lâAction GitHub.
(ex:
uses: bencherdev/bencher@main
) - Utilisez la sous-commande CLI
bencher run
pour exécuter vos benchmarks de la branchemain
. Consultez la sous-commande CLIbencher run
pour un aperçu complet. (ex:bencher run
) - DĂ©finissez lâoption
--project
sur le slug du Projet. Consultez les documents--project
pour plus de détails. (ex:--project save-walter-white-1234abcd
) - DĂ©finissez lâoption
--token
sur le secret RepositoryBENCHER_API_TOKEN
. Consultez les documents--token
pour plus de détails. (ex:--token '${{ secrets.BENCHER_API_TOKEN }}'
) - DĂ©finissez lâoption
--branch
sur le nom de la branche de base. Consultez les documents--branch
pour un aperçu complet. (ex:--branch main
) - RĂ©glez lâoption
--testbed
sur le nom du Testbed. Cela devrait probablement correspondre à la machine sélectionnée dansruns-on
. Consultez les documents--tested
pour plus de détails. (ex:--testbed ubuntu-latest
) - DĂ©finissez le seuil pour la Branche
main
, le Testbedubuntu-latest
, et la Mesurelatency
:- DĂ©finissez lâoption
--threshold-measure
sur la Mesure intégréelatency
générée parbencher mock
. Consultez les documents--threshold-measure
pour plus de détails. (ex:--threshold-measure latency
) - DĂ©finissez lâoption
--threshold-test
sur un test t de Student (t_test
). Consultez les documents--threshold-test
pour un aperçu complet. (ex:--threshold-test t_test
) - DĂ©finissez lâoption
--threshold-max-sample-size
sur la taille maximale de lâĂ©chantillon de64
. Consultez les documents--threshold-max-sample-size
pour plus de détails. (ex:--threshold-max-sample-size 64
) - DĂ©finissez lâoption
--threshold-upper-boundary
sur la Limite Supérieure de0.99
. Consultez les documents--threshold-upper-boundary
pour plus de détails. (ex:--threshold-upper-boundary 0.99
) - RĂ©glez lâindicateur
--thresholds-reset
pour que seul le seuil spécifié soit actif. Consultez les documents--thresholds-reset
pour un aperçu complet. (ex:--thresholds-reset
)
- DĂ©finissez lâoption
- RĂ©glez lâindicateur
--err
pour échouer la commande si une Alerte est générée. Consultez les documents--err
pour un aperçu complet. (ex:--err
) - DĂ©finissez lâoption
--adapter
sur Bencher Metric Format JSON (json
) qui est généré parbencher mock
. Consultez les adaptateurs de harnais de benchmark pour un aperçu complet. (ex:--adapter json
) - RĂ©glez lâoption
--github-actions
sur le jeton dâauthentification API GitHub pour publier les rĂ©sultats sous forme de commentaire de VĂ©rifications GitHub en utilisant la variable dâenvironnementGITHUB_TOKEN
de GitHub Actions. Consultez les documents--github-actions
pour plus de détails. (ex:--github-actions '${{ secrets.GITHUB_TOKEN }}'
) - Spécifiez les arguments de la commande de benchmark.
Consultez la commande de benchmark pour un aperçu complet.
(ex:
bencher mock
)
Pull Requests
Afin de détecter une régression de performance dans les Pull Requests, vous devrez exécuter vos benchmarks sur les PRs.
Si vous vous attendez uniquement Ă recevoir des PRs Ă partir de branches au sein du mĂȘme dĂ©pĂŽt,
alors vous pouvez simplement créer un autre workflow pour fonctionner avec des événements on
pull_request
du mĂȘme dĂ©pĂŽt.
â ïž Cette solution ne fonctionne que si toutes les PRs proviennent du mĂȘme dĂ©pĂŽt ! Voir Pull Requests depuis des Forks ci-dessous.
-
Créez un fichier
workflow
GitHub Actions. (ex :.github/workflows/pr_benchmarks.yml
) -
Exécutez sur des événements
pull_request
:opened
- Une pull request a été créée.reopened
- Une pull request précédemment fermée a été rouverte.edited
- Le titre ou le corps dâune pull request a Ă©tĂ© modifiĂ©, ou la branche de base dâune pull request a Ă©tĂ© changĂ©e.synchronize
- La branche head dâune pull request a Ă©tĂ© mise Ă jour. Par exemple, la branche head a Ă©tĂ© mise Ă jour Ă partir de la branche de base ou de nouveaux commits ont Ă©tĂ© poussĂ©s Ă la branche head.
Consultez la documentation de GitHub Actions
on
et la documentation de GitHub Actionspull_request
pour un aperçu complet. (ex :on: pull_request: types: [opened, reopened, edited, synchronize]
) -
Créez un
job
GitHub Actions. (ex :jobs: benchmark_pr_branch
) -
Exécutez sur des événements
pull_request
uniquement si la pull request vient du mĂȘme dĂ©pĂŽt. â ïž NE SUPPRIMEZ PAS CETTE LIGNE ! Pour gĂ©rer les PRs de Forks, voir Pull Requests depuis des Forks ci-dessous. (ex :if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
) -
DĂ©finissez les permissions pour le
GITHUB_TOKEN
surwrite
pour lespull-requests
. Selon vos paramĂštres GitHub, cela peut ne pas ĂȘtre nĂ©cessaire. Mais pour toutes les organisations et dĂ©pĂŽts personnels crĂ©Ă©s aprĂšs le 02 fĂ©vrier 2023, câest le comportement par dĂ©faut. Voir la documentation GitHub pour un aperçu complet. (ex :permissions: pull-requests: write
) -
DĂ©finissez le type de machine sur laquelle le job sâexĂ©cutera. Voir la documentation
runs-on
de GitHub Actions pour un aperçu complet. (ex :runs-on: ubuntu-latest
) -
Validez le code source de la branche PR. (ex :
uses: actions/checkout@v4
) -
Installez le Bencher CLI en utilisant lâAction GitHub. (ex :
uses: bencherdev/bencher@main
) -
Utilisez la sous-commande CLI
bencher run
pour exécuter vos benchmarks de branche de pull request. Voir la sous-commande CLIbencher run
pour un aperçu complet. (ex :bencher run
) -
DĂ©finissez lâoption
--project
sur le slug du projet. Voir la documentation--project
pour plus de détails. (ex :--project save-walter-white-1234abcd
) -
DĂ©finissez lâoption
--token
sur le secret du dépÎtBENCHER_API_TOKEN
. Voir la documentation--token
pour plus de détails. (ex :--token '${{ secrets.BENCHER_API_TOKEN }}'
) -
DĂ©finissez lâoption
--branch
sur le nom de la branche PR en utilisant la variable dâenvironnement par dĂ©fautGITHUB_HEAD_REF
de GitHub Actions. Voir la documentation--branch
pour un aperçu complet. (ex :--branch "$GITHUB_HEAD_REF"
) -
DĂ©finissez le Point de DĂ©part pour la branche PR :
- DĂ©finissez lâoption
--start-point
sur le point de dĂ©part de la branche PR en utilisant la variable dâenvironnement par dĂ©fautGITHUB_BASE_REF
de GitHub Actions. Voir la documentation--start-point
pour un aperçu complet. (ex :--start-point "$GITHUB_BASE_REF"
) - DĂ©finissez lâoption
--start-point-hash
sur le hashgit
du point de dĂ©part de la branche PR en utilisant lâĂ©vĂ©nementpull_request
de GitHub Actions. Voir la documentation--start-point-hash
pour un aperçu complet. (ex :--start-point-hash '${{ github.event.pull_request.base.sha }}'
) - DĂ©finissez le drapeau
--start-point-clone-thresholds
pour cloner les Seuils à partir du point de départ. Voir la documentation--start-point-clone-thresholds
pour un aperçu complet. (ex :--start-point-clone-thresholds
) - DĂ©finissez le drapeau
--start-point-reset
pour toujours rĂ©initialiser la branche PR au point de dĂ©part. Cela empĂȘchera la dĂ©rive des donnĂ©es de benchmark. Voir la documentation--start-point-reset
pour un aperçu complet. (ex :--start-point-reset
)
- DĂ©finissez lâoption
-
DĂ©finissez lâoption
--testbed
sur le nom du Banc dâEssai. Cela devrait probablement correspondre Ă la machine sĂ©lectionnĂ©e dansruns-on
. Voir la documentation--testbed
pour plus de détails. (ex :--testbed ubuntu-latest
) -
DĂ©finissez le drapeau
--err
pour échouer la commande si une Alerte est générée. Voir la documentation--err
pour un aperçu complet. (ex :--err
) -
DĂ©finissez lâoption
--adapter
sur le Format de MĂ©trique Bencher JSON (json
) généré parbencher mock
. Voir les adaptateurs de harnais de benchmark pour un aperçu complet. (ex :--adapter json
) -
DĂ©finissez lâoption
--github-actions
sur le token dâauthentification de lâAPI GitHub pour poster les rĂ©sultats en tant que commentaire sur la Pull Request en utilisant la variable dâenvironnementGITHUB_TOKEN
de GitHub Actions. Voir la documentation--github-actions
pour plus de détails. (ex :--github-actions '${{ secrets.GITHUB_TOKEN }}'
) -
Spécifiez les arguments de commande de benchmark. Voir la commande de benchmark pour un aperçu complet. (ex :
bencher mock
)
Pour nettoyer la branche PR aprĂšs la fermeture de la PR,
vous pouvez crĂ©er un flux de travail sĂ©parĂ© pour sâexĂ©cuter on
des événements pull_request
avec le type closed
.
Ce flux de travail archivera la branche PR en utilisant la commande bencher archive
.
-
Créez un fichier
workflow
GitHub Actions. (ex:.github/workflows/pr_benchmarks_closed.yml
) -
Exécutez sur les événements
pull_request
:closed
- Une pull request a été fermée.
Consultez la documentation GitHub Actions
on
et la documentation GitHub Actionspull_request
pour un aperçu complet. (ex:on: pull_request: types: [closed]
) -
Créez un
job
GitHub Actions. (ex:jobs: archive_pr_branch
) -
Exécutez sur les événements
pull_request
uniquement si la pull request provient du mĂȘme dĂ©pĂŽt. â ïž NE PAS SUPPRIMER CETTE LIGNE ! Pour gĂ©rer les PRs de fork, voir Pull Requests de Forks ci-dessous. (ex:if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
) -
DĂ©finissez le type de machine sur lequel le job sâexĂ©cutera. Voir la documentation
runs-on
GitHub Actions pour un aperçu complet. (ex:runs-on: ubuntu-latest
) -
Validez le code source de la branche PR. (ex:
uses: actions/checkout@v4
) -
Installez le Bencher CLI en utilisant lâAction GitHub. (ex:
uses: bencherdev/bencher@main
) -
Utilisez la sous-commande CLI
bencher archive
pour archiver la branche PR. (ex:bencher archive
) -
Configurez lâoption
--project
sur le slug du projet. Consultez les documents--project
pour plus de détails. (ex:--project save-walter-white-1234abcd
) -
Configurez lâoption
--token
avec le secret du DĂ©pĂŽtBENCHER_API_TOKEN
. Consultez les documents--token
pour plus de détails. (ex:--token '${{ secrets.BENCHER_API_TOKEN }}'
) -
Configurez lâoption
--branch
sur le nom de la branche PR en utilisant la variable dâenvironnement par dĂ©fautGITHUB_HEAD_REF
de GitHub Actions. (ex:--branch "$GITHUB_HEAD_REF"
)
Demandes de Tirage depuis des Fourches
Si vous envisagez dâaccepter des demandes de tirage depuis des fourches, comme câest souvent le cas dans les projets open source publics, alors vous devrez gĂ©rer les choses un peu diffĂ©remment. Pour des raisons de sĂ©curitĂ©, des secrets tels que votre BENCHER_API_TOKEN
et le GITHUB_TOKEN
ne sont pas disponibles dans les GitHub Actions pour les PRs de fourches. Ainsi, si un contributeur externe ouvre une PR depuis une fourche, lâexemple ci-dessus ne fonctionnera pas. Consultez cette analyse de GitHub Security Lab et cet article de blog sur la prĂ©vention des pwn requests pour un aperçu complet.
Voici la maniÚre sûre et suggérée pour ajouter le benchmarking continu aux demandes de tirage de fourches. Cela nécessite deux workflows distincts. Le premier workflow exécute et met en cache les résultats du benchmark dans le contexte pull_request
. Aucun secret tel que votre BENCHER_API_TOKEN
et le GITHUB_TOKEN
nây est disponible. Ensuite, un second workflow tĂ©lĂ©charge les rĂ©sultats des benchmarks mis en cache dans le contexte workflow_run
et les télécharge vers Bencher. Cela fonctionne car workflow_run
sâexĂ©cute dans le contexte de la branche par dĂ©faut du dĂ©pĂŽt, oĂč des secrets tels que votre BENCHER_API_TOKEN
et le GITHUB_TOKEN
sont disponibles. Le numéro de la demande de tirage, la branche principale et la branche de base utilisées dans le workflow initial pull_request
doivent Ă©galement ĂȘtre explicitement passĂ©s dans le workflow workflow_run
car ils ne sont pas disponibles lĂ -bas. Ces workflows ne sâexĂ©cuteront que sâils existent sur la branche par dĂ©faut. Voir utilisation des donnĂ©es du workflow dĂ©clencheur pour un aperçu complet.
-
Créez un premier fichier
workflow
GitHub Actions. (ex :.github/workflows/fork_pr_benchmarks_run.yml
) -
Nommez ce workflow afin quâil puisse ĂȘtre rĂ©fĂ©rencĂ© par le deuxiĂšme workflow. (ex :
name: Run Benchmarks
) -
Exécutez sur les événements
pull_request
:opened
- Une pull request a été créée.reopened
- Une pull request précédemment fermée a été réouverte.edited
- Le titre ou le corps dâune pull request a Ă©tĂ© modifiĂ©, ou la branche de base dâune pull request a Ă©tĂ© changĂ©e.synchronize
- La branche head dâune pull request a Ă©tĂ© mise Ă jour. Par exemple, la branche head a Ă©tĂ© mise Ă jour Ă partir de la branche de base ou de nouveaux commits ont Ă©tĂ© poussĂ©s vers la branche head.
Voir la documentation GitHub Actions
on
et la documentation GitHub Actionspull_request
pour un aperçu complet. (ex :on: pull_request: types: [opened, reopened, edited, synchronize]
) -
Créez un
job
GitHub Actions. (ex :jobs: benchmark_fork_pr_branch
) -
DĂ©finissez le type de machine sur lequel le job sâexĂ©cutera. Voir la documentation GitHub Actions
runs-on
pour un aperçu complet. (ex :runs-on: ubuntu-latest
) -
Récupérez le code source de la branche fork PR. (ex :
uses: actions/checkout@v4
) -
Exécutez vos benchmarks et enregistrez les résultats dans un fichier. (ex :
/bin/echo '{ ... }' > benchmark_results.json
) -
TĂ©lĂ©chargez le fichier de rĂ©sultats des benchmarks en tant quâartifact. (ex :
uses: actions/upload-artifact@v4
) -
TĂ©lĂ©chargez lâobjet dâĂ©vĂ©nement
pull_request
en tant quâartifact. (ex :uses: actions/upload-artifact@v4
)
- Créez un premier fichier de
workflow
GitHub Actions. (ex :.github/workflows/fork_pr_benchmarks_track.yml
) - Nommez ce workflow second workflow.
(ex :
name: Track Benchmarks with Bencher
) - EnchaĂźnez les deux workflows avec
lâĂ©vĂ©nement
workflow_run
. (ex :on: workflow_run: ...
) - Créez un
job
GitHub Actions. (ex :jobs: track_fork_pr_branch
) - Exécutez ce job uniquement si la conclusion du précédent workflow était un succÚs en utilisant
lâĂ©vĂ©nement
workflow_run
de GitHub Actions. (ex :if: github.event.workflow_run.conclusion == 'success'
) - DĂ©finissez le type de machine sur lequel le job sâexĂ©cutera.
Consultez la documentation
runs-on
de GitHub Actions pour un aperçu complet. (ex :runs-on: ubuntu-latest
) - DĂ©finissez les rĂ©sultats des benchmarks et les noms des fichiers dâobjets de lâĂ©vĂ©nement
pull_request
comme variables dâenvironnement. (ex :env: ...
) - TĂ©lĂ©chargez les rĂ©sultats des benchmarks mis en cache et lâĂ©vĂ©nement
pull_request
en utilisant lâAction GitHubaction-download-artifact
. (ex :uses: dawidd6/action-download-artifact@v6
) - Exportez les donnĂ©es nĂ©cessaires de lâĂ©vĂ©nement
pull_request
en tant que variables dâenvironnement. (ex :core.exportVariable(...)
) - Installez le CLI Bencher en utilisant lâAction GitHub.
(ex :
uses: bencherdev/bencher@main
) - Utilisez la sous-commande CLI
bencher run
pour suivre les benchmarks de votre branche pull fork. Consultez la sous-commande CLIbencher run
pour un aperçu complet. (ex :bencher run
) - DĂ©finissez lâoption
--project
sur le slug du Projet. Consultez la documentation--project
pour plus de détails. (ex :--project save-walter-white-1234abcd
) - DĂ©finissez lâoption
--token
sur le secret RepositoryBENCHER_API_TOKEN
. Consultez la documentation--token
pour plus de détails. (ex :--token '${{ secrets.BENCHER_API_TOKEN }}'
) - DĂ©finissez lâoption
--branch
sur le nom de la branche PR fork en utilisant une variable dâenvironnement intermĂ©diaire. Consultez la documentation--branch
pour un aperçu complet. (ex :--branch "$PR_HEAD"
) - DĂ©finissez le Point de DĂ©part pour la branche PR fork :
- DĂ©finissez lâoption
--start-point
sur le point de dĂ©part de la branche PR fork en utilisant une variable dâenvironnement intermĂ©diaire. Consultez la documentation--start-point
pour un aperçu complet. (ex :--start-point "$PR_BASE"
) - DĂ©finissez lâoption
--start-point-hash
sur le hashgit
du point de dĂ©part de la branche PR fork en utilisant une variable dâenvironnement intermĂ©diaire. Consultez la documentation--start-point-hash
pour un aperçu complet. (ex :--start-point-hash "$PR_BASE_SHA"
) - DĂ©finissez le drapeau
--start-point-clone-thresholds
pour cloner les Seuils à partir du point de départ. Consultez la documentation--start-point-clone-thresholds
pour un aperçu complet. (ex :--start-point-clone-thresholds
) - DĂ©finissez le drapeau
--start-point-reset
pour toujours rĂ©initialiser la branche PR fork au point de dĂ©part. Cela empĂȘchera la dĂ©rive des donnĂ©es de benchmark. Consultez la documentation--start-point-reset
pour un aperçu complet. (ex :--start-point-reset
)
- DĂ©finissez lâoption
- DĂ©finissez lâoption
--testbed
sur le nom du Testbed. Cela devrait probablement correspondre à la machine sélectionnée dansruns-on
. Consultez la documentation--tested
pour plus de détails. (ex :--testbed ubuntu-latest
) - DĂ©finissez le drapeau
--err
pour échouer la commande si une Alerte est générée. Consultez la documentation--err
pour un aperçu complet. (ex :--err
) - DĂ©finissez lâoption
--adapter
sur Bencher Metric Format JSON (json
) qui est généré parbencher mock
. Consultez la documentation benchmark harness adapters pour un aperçu complet. (ex :--adapter json
) - DĂ©finissez lâoption
--github-actions
sur le jeton dâauthentification de lâAPI GitHub pour publier les rĂ©sultats en tant que commentaire sur le Pull Request en utilisant la variable dâenvironnementGITHUB_TOKEN
de GitHub Actions. Consultez la documentation--github-actions
pour plus de détails. (ex :--github-actions '${{ secrets.GITHUB_TOKEN }}'
) - DĂ©finissez lâoption
--ci-number
sur le numĂ©ro de la pull request en utilisant une variable dâenvironnement intermĂ©diaire. Consultez la documentation--ci-number
pour plus de détails. (ex :--ci-number "$PR_NUMBER"
) - DĂ©finissez lâoption
--file
sur le chemin du fichier de résultats des benchmarks. Consultez la documentation benchmark command pour un aperçu complet. (ex :--file "$BENCHMARK_RESULTS"
)
Pour nettoyer la branche de PR fork aprĂšs la fermeture de sa PR,
vous pouvez crĂ©er un flux de travail sĂ©parĂ© pour sâexĂ©cuter lors des Ă©vĂ©nements on
pull_request_target
de type closed
.
Ce flux de travail archivera la branche de PR fork en utilisant la commande bencher archive
.
-
Créez un fichier de
workflow
GitHub Actions. (ex :.github/workflows/fork_pr_benchmarks_closed.yml
) -
Exécutez sur les événements
pull_request_target
:closed
- Une pull request a été fermée.
Consultez la documentation
on
de GitHub Actions et la documentationpull_request_target
de GitHub Actions pour un aperçu complet. (ex :on: pull_request_target: types: [closed]
) -
Créez un
job
GitHub Actions. (ex :jobs: archive_pr_branch
) -
DĂ©finissez le type de machine sur laquelle le job sâexĂ©cutera. Consultez la documentation
runs-on
de GitHub Actions pour un aperçu complet. (ex :runs-on: ubuntu-latest
) -
Récupérez le code source de la branche PR. (ex :
uses: actions/checkout@v4
) -
Installez le Bencher CLI en utilisant lâaction GitHub. (ex :
uses: bencherdev/bencher@main
) -
Utilisez la sous-commande CLI
bencher archive
pour archiver la branche PR. (ex :bencher archive
) -
DĂ©finissez lâoption
--project
avec le slug du projet. Consultez la documentation de lâoption--project
pour plus de détails. (ex :--project save-walter-white-1234abcd
) -
DĂ©finissez lâoption
--token
avec le secret de RepositoryBENCHER_API_TOKEN
. Consultez la documentation de lâoption--token
pour plus de détails. (ex :--token '${{ secrets.BENCHER_API_TOKEN }}'
) -
DĂ©finissez lâoption
--branch
avec le nom de la branche PR en utilisant la variable dâenvironnement par dĂ©fautGITHUB_HEAD_REF
de GitHub Actions. (ex :--branch "$GITHUB_HEAD_REF"
)
đ° FĂ©licitations ! Vous avez appris comment utiliser Bencher dans GitHub Actions ! đ