Vous utilisez GitHub pour versionner votre app ASP.NET Core ou Blazor, et vous hébergez sur SmarterASP.NET ? Ce guide vous montre comment automatiser entièrement vos déploiements avec GitHub Actions, sans quitter l'écosystème GitHub, sans outil tiers, et sans copier un seul fichier à la main.
TL;DR
- GitHub Actions orchestre le build et le déploiement depuis votre dépôt, sur un runner Windows (nécessaire pour MSDeploy).
- SmarterASP.NET expose un endpoint WebDeploy (MSDeploy) sur le port 8172, on s'en sert directement.
- Les secrets (credentials, mot de passe) sont stockés dans les GitHub Secrets, les variables non-sensibles dans les GitHub Variables.
- Des règles
-skipprotègent vos fichiers critiques côté serveur (certificats Let's Encrypt, sitemaps…).
GitHub Actions vs Azure DevOps : lequel choisir ?
Si votre code est déjà sur GitHub, GitHub Actions est le choix naturel : tout est au même endroit, la configuration est dans le dépôt, et le modèle gratuit est généreux (2 000 minutes/mois pour les dépôts privés). Azure DevOps reste pertinent si vous avez déjà un écosystème Microsoft (boards, artifacts, test plans), mais pour un projet .NET hébergé sur SmarterASP.NET, GitHub Actions fait le travail sans friction.
La logique de déploiement est identique dans les deux cas : dotnet publish produit un dossier, msdeploy.exe le synchronise avec le serveur. Seule la syntaxe du fichier de configuration change.
ℹ Pré-requis
Vous avez besoin d'un compte GitHub, d'un dépôt contenant votre projet .NET, et de vos identifiants SmarterASP.NET (username / password de votre panneau de contrôle). WebDeploy doit être activé dans les paramètres de votre site.
Pas encore client ? Mon lien partenaire vous donne accès à une offre promotionnelle.
Anatomie du workflow
Un workflow GitHub Actions est un fichier YAML placé dans .github/workflows/. Il se compose de jobs, eux-mêmes composés de steps. Ici, on fait tout dans un seul job build_and_deploy pour garder les choses simples, le publish est le résultat direct du build, inutile de stocker un artefact intermédiaire.
push sur main
└── job: build_and_deploy (windows-latest)
├── Checkout
├── Setup .NET
├── Restore
├── Build
├── Publish
├── WebDeploy → SmarterASP.NET
└── Warm-up
✓ Pourquoi
windows-latest?
msdeploy.exeest un outil Windows uniquement. Les runners Ubuntu ou macOS ne peuvent pas l'exécuter. GitHub fournit des runners Windows dans son offre gratuite, donc ce n'est pas un problème.
Le workflow complet et commenté
Créez le fichier .github/workflows/deploy.yml dans votre dépôt :
name: Build & Deploy to SmarterASP.NET
# Déclencheurs : push sur main, ou lancement manuel depuis l'interface GitHub
on:
push:
branches: [ main ]
workflow_dispatch: # Permet de relancer manuellement depuis l'onglet Actions
jobs:
build_and_deploy:
runs-on: windows-latest # Obligatoire : msdeploy.exe n'existe que sur Windows
environment: prod # Environnement GitHub (permet les règles de protection et approbations)
steps:
# 1. Récupère le code source
- name: Checkout
uses: actions/checkout@v4
# 2. Installe le SDK .NET demandé
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x' # Adaptez à votre version cible
# 3. Restaure les dépendances NuGet
- name: Restore
run: dotnet restore src/YourApp/YourApp.csproj
# 4. Compile en mode Release
- name: Build
run: dotnet build src/YourApp/YourApp.csproj --configuration Release --no-restore
# 5. Publie l'application dans le dossier ./publish
# --no-build évite de recompiler ce qui vient d'être compilé
- name: Publish
run: dotnet publish src/YourApp/YourApp.csproj --configuration Release --output publish --no-build
# 6. Déploie via WebDeploy (MSDeploy) vers SmarterASP.NET
- name: WebDeploy to SmarterASP.NET
shell: pwsh
env:
# Variables non-sensibles : stockées dans GitHub Variables (Settings → Variables)
WEBSITE_NAME: ${{ vars.WEBDEPLOY_WEBSITE_NAME }}
SERVER_COMPUTER_NAME: ${{ vars.WEBDEPLOY_SERVER_URL }}
SERVER_USERNAME: ${{ vars.WEBDEPLOY_USERNAME }}
PARAM_EXCLUDED_FILES: ${{ vars.EXCLUDED_FILES }}
PRESERVE_REMOTE_FILES: ${{ vars.PRESERVE_REMOTE_FILES }}
# Secret sensible : stocké dans GitHub Secrets (Settings → Secrets)
SERVER_PASSWORD: ${{ secrets.WEBDEPLOY_PASSWORD }}
run: |
# Recherche msdeploy aux deux emplacements standards des runners Windows
$msdeploy = @(
"C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe",
"C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe"
) | Where-Object { Test-Path $_ } | Select-Object -First 1
if (-not $msdeploy) { throw "msdeploy.exe introuvable sur ce runner" }
Write-Host "msdeploy trouvé : $msdeploy"
Write-Host "Déploiement vers : $env:WEBSITE_NAME"
$sourcePath = "$PWD\publish"
$msdeployArgs = @(
"-verb:sync",
"-source:contentPath=$sourcePath",
"-dest:contentPath=$env:WEBSITE_NAME,computerName=$env:SERVER_COMPUTER_NAME,userName=$env:SERVER_USERNAME,password=$env:SERVER_PASSWORD,authtype=Basic,includeAcls=False",
"-allowUntrusted", # Utile si la chaîne de certificat pose problème sur le runner
"-disableLink:AppPoolExtension",
"-disableLink:ContentExtension",
"-disableLink:CertificateExtension",
"-enableRule:AppOffline" # Place un app_offline.htm pendant le déploiement
)
# Option : ne pas supprimer les fichiers inconnus côté serveur
if ($env:PRESERVE_REMOTE_FILES -eq "true") {
$msdeployArgs += "-enableRule:DoNotDeleteRule"
}
# --- Exclusions personnalisées (via variable EXCLUDED_FILES) ---
$env:PARAM_EXCLUDED_FILES -split ";" | Where-Object { $_.Trim() -ne "" } | ForEach-Object {
$regex = "(?i).*$([Regex]::Escape($_.Trim()))$"
Write-Host "Exclusion fichier : $regex"
$msdeployArgs += "-skip:skipAction=Delete,objectName=filePath,absolutePath=$regex"
}
# --- Protéger les dossiers critiques côté serveur ---
# Certificats Let's Encrypt (dossier ACME challenge)
$msdeployArgs += "-skip:skipAction=Delete,objectName=dirPath,absolutePath=(?i).*\\\.well-known.*"
# Sitemaps générés dynamiquement par l'application au runtime
$msdeployArgs += "-skip:skipAction=Delete,objectName=dirPath,absolutePath=(?i).*\\wwwroot\\sitemaps(`$|\\.*)"
$msdeployArgs += "-skip:skipAction=Delete,objectName=filePath,absolutePath=(?i).*\\wwwroot\\sitemaps\\.*"
Write-Host "Lancement de msdeploy..."
& $msdeploy @msdeployArgs
# Vérifie le code de sortie PowerShell ne propage pas toujours les erreurs automatiquement
if ($LASTEXITCODE -ne 0) {
Write-Error "msdeploy a échoué avec le code $LASTEXITCODE"
exit $LASTEXITCODE
}
# 7. Warm-up : envoie une requête HTTP pour sortir l'app de sa veille au démarrage
- name: Warm-up application
shell: pwsh
continue-on-error: true # Un warm-up raté ne doit pas invalider un déploiement réussi
run: |
$url = "${{ vars.WEBSITE_URL }}"
$maxRetries = 3
$retryDelay = 10
Write-Host "Warm-up de $url..."
for ($i = 1; $i -le $maxRetries; $i++) {
try {
$r = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 45
Write-Host "Site répond : $($r.StatusCode) - OK"
break
} catch {
Write-Host "Tentative $i/$maxRetries échouée : $_"
if ($i -lt $maxRetries) { Start-Sleep -Seconds $retryDelay }
}
}
Variables et secrets à configurer dans GitHub
Rendez-vous dans Settings → Secrets and variables → Actions de votre dépôt. GitHub distingue deux catégories :
- Secrets : chiffrés, jamais affichés dans les logs, accessibles via
${{ secrets.NOM }} - Variables : en clair dans l'interface, accessibles via
${{ vars.NOM }}
| Nom | Type | Exemple de valeur |
|---|---|---|
WEBDEPLOY_WEBSITE_NAME |
Variable | monsite.com |
WEBDEPLOY_SERVER_URL |
Variable | https://win1234.site4now.net:8172/msdeploy.axd?site=monsite.com |
WEBDEPLOY_USERNAME |
Variable | votre-login-smarterasp |
WEBDEPLOY_PASSWORD |
Secret | ••••••••• |
WEBSITE_URL |
Variable | https://monsite.com |
EXCLUDED_FILES |
Variable | appsettings.Production.json;Web.config |
PRESERVE_REMOTE_FILES |
Variable | false |
✓ Conseil
Retrouvez votreWEBDEPLOY_SERVER_URLdans le panneau de contrôle SmarterASP.NET → Publish your website → onglet Connection. Il commence toujours parhttps://winXXXX.site4now.net:8172.
L'environnement prod et les règles de protection
Le workflow référence environment: prod. Pour créer cet environnement dans GitHub, allez dans Settings → Environments → New environment, nommez-le prod.
L'intérêt ? Vous pouvez y ajouter :
- Des reviewers requis, un collaborateur doit approuver avant que le déploiement parte.
- Un délai d'attente, par exemple 5 minutes entre le push et le déploiement effectif.
- Des branches autorisées, seule la branche
mainpeut déclencher un déploiement versprod.
C'est l'équivalent des approbations dans Azure DevOps Environments, directement intégré à GitHub.
Étape par étape : mettre ça en place
Activez WebDeploy dans le panneau SmarterASP.NET. Vérifiez que le port 8172 est accessible depuis l'extérieur.
Créez le fichier
.github/workflows/deploy.ymlà la racine de votre dépôt. Copiez le YAML ci-dessus et adaptez le chemin vers votre.csprojet la version .NET.Ajoutez les secrets et variables dans Settings → Secrets and variables → Actions de votre dépôt GitHub.
Créez l'environnement
proddans Settings → Environments. Ajoutez une règle de protection si vous travaillez en équipe.Poussez sur
mainet observez l'onglet Actions de votre dépôt. Chaque step affiche ses logs en temps réel.En cas d'échec, cliquez sur le step incriminé pour voir le message d'erreur. msdeploy est généralement très explicite (mauvais credentials, port fermé, etc.).
Les pièges courants
« msdeploy introuvable »
Les runners windows-latest de GitHub incluent Web Deploy V3. Le script cherche aux deux emplacements classiques. Si ça échoue, ajoutez un step d'installation avant le déploiement :
- name: Install WebDeploy
run: choco install webdeploy -y
shell: pwsh
Mon appsettings.Production.json est écrasé
Ajoutez-le dans la variable EXCLUDED_FILES : appsettings.Production.json. Le script PowerShell le transforme en règle -skip qui protège le fichier côté serveur à chaque déploiement.
⚠ Attention
Ne versionnez jamais vos secrets de production dansappsettings.json. Utilisezappsettings.Production.jsonhors dépôt, ou GitHub Secrets + injection via les variables d'environnement au runtime.
Le warm-up échoue avec une 302 ou une erreur SSL
Normal si votre site redirige HTTP → HTTPS. Le continue-on-error: true sur le step warm-up fait que GitHub ne considère pas ça comme un échec du workflow. Le déploiement est bien terminé.
Différence avec Azure DevOps : pas d'artefact intermédiaire
Dans la pipeline Azure DevOps de l'article précédent, on publiait un artefact entre le stage Build et le stage Deploy. Ici, comme tout se passe dans un seul job, le dossier ./publish est directement accessible au step suivant. C'est plus simple, mais ça signifie aussi qu'on ne peut pas réutiliser cet artefact pour un second environnement sans restructurer le workflow en plusieurs jobs.
Aller plus loin
Séparer build et deploy en deux jobs
Si vous voulez ajouter des tests automatisés ou déployer vers plusieurs environnements depuis le même artefact, séparez le workflow en deux jobs : un job build qui uploade un artefact via actions/upload-artifact, et un job deploy qui le télécharge via actions/download-artifact. C'est l'équivalent de la structure en stages d'Azure DevOps.
Déclencher uniquement sur certains chemins
Pour éviter de redéployer quand seul un fichier de documentation change :
on:
push:
branches: [ main ]
paths:
- 'src/**'
- '.github/workflows/deploy.yml'
Notifications en cas d'échec
Ajoutez un step conditionnel en fin de workflow :
- name: Notifier en cas d'échec
if: failure()
run: |
# Appel webhook Teams, Slack, ou autre
Invoke-RestMethod -Uri "${{ secrets.SLACK_WEBHOOK }}" -Method Post -Body '{"text":"🚨 Déploiement échoué sur main"}'
shell: pwsh
✓ Bonne pratique finale
Activez les branch protection rules surmaindans Settings → Branches. Exigez que les pull requests passent par une review avant le merge. Combiné à l'environnementprodavec approbation, vous avez un workflow de déploiement solide sans aucun outil externe.
Conclusion
GitHub Actions rend le déploiement continu vers SmarterASP.NET accessible en moins d'une heure de configuration. Tout vit dans votre dépôt, la configuration est versionnée, et l'historique des déploiements est visible directement dans l'onglet Actions. C'est une alternative sérieuse à Azure DevOps pour les projets qui n'ont pas besoin de l'écosystème complet Microsoft.
Si vous avez déjà lu l'article sur Azure DevOps Pipelines, vous remarquerez que la logique PowerShell/MSDeploy est quasi identique, seul l'habillage YAML change. C'est voulu : une fois que vous maîtrisez WebDeploy, vous pouvez passer d'un outil CI/CD à l'autre sans réapprendre le mécanisme de déploiement.
Des questions sur les migrations EF Core au déploiement, la gestion multi-environnements, ou les GitHub Environments ? Les commentaires sont là pour ça.


Commentaires (0)
Aucun commentaire pour le moment. Soyez le premier à commenter !
Laisser un commentaire