Il tag git diventa la fonte unica della versione

Il .csproj non viene piu' riscritto a ogni rilascio: i quattro numeri di
versione arrivano a dotnet publish come proprieta' da riga di comando, ricavati
dal tag su HEAD. Tag, eseguibile, installatore e release portano lo stesso
numero per costruzione invece che per disciplina, e un rilascio non lascia piu'
una modifica al progetto da committare dopo il fatto.

Se HEAD non ha un tag la catena lo crea da se' — numero chiesto o minor
successiva alla piu' alta esistente — ma lo fa in fondo, a installatore
prodotto: un giro fallito non lascia dietro il tag di una versione mai
costruita. Rifiuta di taggare un albero con modifiche non committate, perche'
sarebbe un tag che non indica niente di ricostruibile.

La configurazione di Gitea viene letta prima di compilare: senza token ci si
ferma in due secondi invece che dopo tre minuti di build.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-04 22:38:45 +02:00
co-authored by Claude Opus 5
parent 52e5f68da0
commit 94843311b4
2 changed files with 189 additions and 102 deletions
+3 -3
View File
@@ -68,7 +68,7 @@
}, },
{ {
"label": "crea installatore", "label": "crea installatore",
"detail": "Chiede la versione, verifica, pubblica ed esegue Inno Setup: bin/installer/AutoBidder-<versione>-setup.exe. Non tocca Gitea.", "detail": "Verifica, pubblica ed esegue Inno Setup: bin/installer/AutoBidder-<versione>-setup.exe. Crea il tag a pacchetto pronto. Non tocca Gitea.",
"type": "process", "type": "process",
"command": "dotnet", "command": "dotnet",
"args": [ "args": [
@@ -101,7 +101,7 @@
}, },
{ {
"label": "rilascia su Gitea", "label": "rilascia su Gitea",
"detail": "Chiede versione e note, poi: verifica, pubblica, installatore, tag e release su Gitea con i file allegati. Richiede build/gitea.json.", "detail": "Verifica, pubblica, installatore, tag e release su Gitea con i file allegati. La versione viene dal tag su HEAD. Richiede build/gitea.json.",
"type": "process", "type": "process",
"command": "dotnet", "command": "dotnet",
"args": [ "args": [
@@ -121,7 +121,7 @@
{ {
"id": "versione", "id": "versione",
"type": "promptString", "type": "promptString",
"description": "Versione (vuoto = incrementa la minor, es. 4.11.0 → 4.12.0)", "description": "Versione — lascia vuoto se hai già taggato (git tag v4.14.0), o per la minor successiva",
"default": "" "default": ""
}, },
{ {
+186 -99
View File
@@ -18,12 +18,24 @@
parlare con Gitea) sta in attività C# in linea: si legge come codice, non parlare con Gitea) sta in attività C# in linea: si legge come codice, non
come una successione di comandi. come una successione di comandi.
── Chi chiede la versione ─────────────────────────────────────────────── ── Da dove viene la versione ────────────────────────────────────────────
MSBuild non può chiedere niente a nessuno: è un motore di compilazione, non Dal tag git, e da nient'altro. Il .csproj non viene mai riscritto: il numero
un programma interattivo. La domanda la fa l'attività di VS Code, che passa arriva a `dotnet publish` come proprietà da riga di comando, quindi tag,
qui la risposta in `-p:Versione=`. Lasciandola vuota si prende la minor eseguibile, installatore e release portano lo stesso numero per costruzione,
successiva a quella scritta nel .csproj — che è il caso normale, e infatti è non per disciplina.
il predefinito del prompt.
Il modo previsto è taggare e poi rilasciare:
git tag v4.14.0
dotnet msbuild build/Release.proj -t:Rilascia
Se HEAD non ha un tag di versione la catena lo crea da sé — con il numero
passato in `-p:Versione=`, oppure la minor successiva all'ultimo tag — e lo
fa in fondo, quando l'installatore esiste davvero. Un giro andato male non
lascia dietro un tag per una versione che non è mai stata costruita.
Il numero nel .csproj resta quello delle compilazioni di sviluppo, e non
c'entra più con i rilasci.
--> -->
<Project DefaultTargets="Pacchetto" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Pacchetto" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
@@ -51,7 +63,8 @@
alterni, senza che il codice fosse cambiato. --> alterni, senza che il codice fosse cambiato. -->
<CartellaProve>$([System.IO.Path]::GetTempPath())AutoBidder.Verifica</CartellaProve> <CartellaProve>$([System.IO.Path]::GetTempPath())AutoBidder.Verifica</CartellaProve>
<!-- Vuoto = incrementa la minor. Vedi TrovaVersione. --> <!-- Serve solo quando HEAD non è ancora taggato: è il numero del tag da
creare. Vuoto = la minor successiva all'ultimo tag. Vedi VersioneDaTag. -->
<Versione Condition="'$(Versione)' == ''"></Versione> <Versione Condition="'$(Versione)' == ''"></Versione>
<!-- Note di rilascio; vuote = ricavate dai commit dall'ultimo tag. --> <!-- Note di rilascio; vuote = ricavate dai commit dall'ultimo tag. -->
@@ -74,84 +87,129 @@
<SaltaVerifica Condition="'$(SaltaVerifica)' == ''">false</SaltaVerifica> <SaltaVerifica Condition="'$(SaltaVerifica)' == ''">false</SaltaVerifica>
<Sovrascrivi Condition="'$(Sovrascrivi)' == ''">false</Sovrascrivi> <Sovrascrivi Condition="'$(Sovrascrivi)' == ''">false</Sovrascrivi>
<Bozza Condition="'$(Bozza)' == ''">false</Bozza> <Bozza Condition="'$(Bozza)' == ''">false</Bozza>
<!-- Un rilascio da albero sporco produce un tag che non corrisponde a
nessuno stato ricostruibile: è esattamente la garanzia che il tag come
fonte unica dovrebbe dare. Si può forzare, ma va detto. -->
<ConsentiModifiche Condition="'$(ConsentiModifiche)' == ''">false</ConsentiModifiche>
</PropertyGroup> </PropertyGroup>
<!-- ═════════════════════ Attività in linea ═════════════════════ --> <!-- ═════════════════════ Attività in linea ═════════════════════ -->
<UsingTask TaskName="TrovaVersione" TaskFactory="RoslynCodeTaskFactory" <!--
Decide quale versione si sta costruendo, senza toccare niente.
Il tag su HEAD, se c'è, comanda: è la fonte. Se non c'è se ne propone uno —
il numero chiesto, o la minor successiva al tag più alto esistente — che
verrà creato solo a pacchetto pronto, da CreaTag.
-->
<UsingTask TaskName="VersioneDaTag" TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll"> AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup> <ParameterGroup>
<Csproj ParameterType="System.String" Required="true" /> <TagsHead ParameterType="System.String" />
<TagsTutti ParameterType="System.String" />
<Richiesta ParameterType="System.String" /> <Richiesta ParameterType="System.String" />
<SoloLettura ParameterType="System.Boolean" /> <Csproj ParameterType="System.String" Required="true" />
<Attuale ParameterType="System.String" Output="true" /> <Versione ParameterType="System.String" Output="true" />
<Effettiva ParameterType="System.String" Output="true" /> <Tag ParameterType="System.String" Output="true" />
<DaCreare ParameterType="System.String" Output="true" />
</ParameterGroup> </ParameterGroup>
<Task> <Task>
<Using Namespace="System" /> <Using Namespace="System" />
<Using Namespace="System.IO" /> <Using Namespace="System.IO" />
<Using Namespace="System.Collections.Generic" />
<Using Namespace="System.Text.RegularExpressions" /> <Using Namespace="System.Text.RegularExpressions" />
<Code Type="Fragment" Language="cs"> <Code Type="Fragment" Language="cs">
<![CDATA[ <![CDATA[
var testo = File.ReadAllText(Csproj); // ConsoleToMSBuild unisce le righe con il punto e virgola; git le separa
var m = Regex.Match(testo, @"<Version>([^<]+)</Version>"); // con a-capo. Si accettano entrambi e non si fanno domande.
if (!m.Success) { Log.LogError("<Version> non trovato in " + Csproj); return false; } Func<string, string[]> spezza = s =>
(s ?? "").Split(new[] { ';', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
Attuale = m.Groups[1].Value.Trim(); var forma = new Regex(@"^v(\d+)\.(\d+)\.(\d+)$");
// Rilettura secca: serve solo a sapere cosa c'e' scritto adesso, senza var suHead = new List<string>();
// proporre incrementi e senza scrivere una riga di registro fuorviante. foreach (var t in spezza(TagsHead))
if (SoloLettura) { Effettiva = Attuale; return true; } if (forma.IsMatch(t.Trim())) suHead.Add(t.Trim());
if (suHead.Count > 1)
{
Log.LogError(
"HEAD ha piu' di un tag di versione (" + string.Join(", ", suHead) + ").\n" +
"Non si puo' sapere quale sia il rilascio: tienine uno solo con git tag -d <tag>");
return false;
}
var chiesta = (Richiesta ?? "").Trim(); var chiesta = (Richiesta ?? "").Trim();
if (chiesta.Length > 0) if (chiesta.Length > 0 && !Regex.IsMatch(chiesta, @"^\d+\.\d+\.\d+$"))
{ {
// Una versione scritta a mano si accetta solo se ha la forma giusta: // Un refuso qui produrrebbe un tag e un pacchetto sbagliati.
// un refuso qui produrrebbe un tag e un pacchetto sbagliati. Log.LogError("Versione '" + chiesta + "' non valida: serve la forma X.Y.Z");
if (!Regex.IsMatch(chiesta, @"^\d+\.\d+\.\d+$")) return false;
}
if (suHead.Count == 1)
{
var dalTag = suHead[0].Substring(1);
if (chiesta.Length > 0 && chiesta != dalTag)
{ {
Log.LogError("Versione '" + chiesta + "' non valida: serve la forma X.Y.Z"); Log.LogError(
"HEAD e' gia' taggato " + suHead[0] + ", ma e' stata chiesta la versione " + chiesta + ".\n" +
"Il tag e' la fonte: o rilasci " + dalTag + " lasciando vuota la versione,\n" +
"oppure togli il tag con git tag -d " + suHead[0] + " e rilancia.");
return false; return false;
} }
Effettiva = chiesta;
Versione = dalTag;
Tag = suHead[0];
DaCreare = "false";
Log.LogMessage(MessageImportance.High, " versione " + Versione + " — dal tag " + Tag + " su HEAD");
return true;
}
if (chiesta.Length > 0)
{
Versione = chiesta;
} }
else else
{ {
// Vuota: la minor successiva. E' il caso normale di una sessione di lavoro. // La minor successiva al tag piu' alto: cosi' il numero proposto e'
var p = Attuale.Split('.'); // sempre libero, anche se il tag piu' alto sta su un altro ramo.
if (p.Length < 2) { Log.LogError("Versione attuale illeggibile: " + Attuale); return false; } int maggiore = -1, minore = -1;
Effettiva = p[0] + "." + (int.Parse(p[1]) + 1) + ".0"; foreach (var t in spezza(TagsTutti))
{
var m = forma.Match(t.Trim());
if (!m.Success) continue;
int ma = int.Parse(m.Groups[1].Value), mi = int.Parse(m.Groups[2].Value);
if (ma > maggiore || (ma == maggiore && mi > minore)) { maggiore = ma; minore = mi; }
}
if (maggiore < 0)
{
// Primo rilascio: non c'e' nessun tag da cui ripartire, e l'unico
// numero che esiste e' quello delle compilazioni di sviluppo.
var testo = File.Exists(Csproj) ? File.ReadAllText(Csproj) : "";
var m = Regex.Match(testo, @"<Version>(\d+)\.(\d+)\.\d+</Version>");
if (!m.Success)
{
Log.LogError(
"Nessun tag di versione nel repository e <Version> illeggibile in " + Csproj + ".\n" +
"Indica la versione con -p:Versione=X.Y.Z");
return false;
}
maggiore = int.Parse(m.Groups[1].Value);
minore = int.Parse(m.Groups[2].Value);
}
Versione = maggiore + "." + (minore + 1) + ".0";
} }
Log.LogMessage(MessageImportance.High, " versione: " + Attuale + " -> " + Effettiva); Tag = "v" + Versione;
]]> DaCreare = "true";
</Code> Log.LogMessage(MessageImportance.High, " versione " + Versione + " — il tag " + Tag + " sara' creato a pacchetto pronto");
</Task>
</UsingTask>
<UsingTask TaskName="ScriviVersione" TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<Csproj ParameterType="System.String" Required="true" />
<Versione ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Using Namespace="System.Text.RegularExpressions" />
<Code Type="Fragment" Language="cs">
<![CDATA[
var testo = File.ReadAllText(Csproj);
// Quattro elementi, un solo numero: Utilities/AppInfo li legge a runtime, e
// vederne divergere uno significa un titolo finestra che mente.
testo = Regex.Replace(testo, @"<Version>[^<]+</Version>", "<Version>" + Versione + "</Version>");
testo = Regex.Replace(testo, @"<AssemblyVersion>[^<]+</AssemblyVersion>", "<AssemblyVersion>" + Versione + ".0</AssemblyVersion>");
testo = Regex.Replace(testo, @"<FileVersion>[^<]+</FileVersion>", "<FileVersion>" + Versione + ".0</FileVersion>");
testo = Regex.Replace(testo, @"<InformationalVersion>[^<]+</InformationalVersion>", "<InformationalVersion>" + Versione + "</InformationalVersion>");
File.WriteAllText(Csproj, testo);
Log.LogMessage(MessageImportance.High, " .csproj aggiornato a " + Versione);
]]> ]]>
</Code> </Code>
</Task> </Task>
@@ -238,7 +296,8 @@
"Configurazione di Gitea incompleta. Servono url, owner, repo, token:\n" + "Configurazione di Gitea incompleta. Servono url, owner, repo, token:\n" +
" copia build/gitea.example.json in build/gitea.json e riempilo,\n" + " copia build/gitea.example.json in build/gitea.json e riempilo,\n" +
" oppure imposta GITEA_URL, GITEA_OWNER, GITEA_REPO, GITEA_TOKEN.\n" + " oppure imposta GITEA_URL, GITEA_OWNER, GITEA_REPO, GITEA_TOKEN.\n" +
"Il pacchetto e' comunque pronto in bin/installer."); "Non e' stato costruito niente: si controlla prima di compilare, non dopo.\n" +
"Per il solo installatore, senza Gitea, usa il target Pacchetto.");
// Senza questo il target prosegue lo stesso: git tag, poi curl con // Senza questo il target prosegue lo stesso: git tag, poi curl con
// l'indirizzo vuoto, e infine un "codice 3" che non dice niente a // l'indirizzo vuoto, e infine un "codice 3" che non dice niente a
@@ -316,7 +375,7 @@
<!-- ═════════════════════ Verifica ═════════════════════ --> <!-- ═════════════════════ Verifica ═════════════════════ -->
<Target Name="Verifica"> <Target Name="Verifica" Condition="'$(SaltaVerifica)' != 'true'">
<Message Importance="High" Text="== Verifica (compilazione + test) ==" /> <Message Importance="High" Text="== Verifica (compilazione + test) ==" />
<!-- In una cartella a parte: l'applicazione puo' essere aperta e tenere <!-- In una cartella a parte: l'applicazione puo' essere aperta e tenere
@@ -352,12 +411,19 @@
<!-- ═════════════════════ Eseguibile ═════════════════════ --> <!-- ═════════════════════ Eseguibile ═════════════════════ -->
<Target Name="Pubblica"> <!--
<Message Importance="High" Text="== Pubblicazione dell'eseguibile ==" /> I quattro numeri di versione arrivano da qui, non dal .csproj: le proprietà
da riga di comando sono globali e vincono su quelle scritte nel progetto.
Vanno passati tutti e quattro — il .csproj li assegna esplicitamente, quindi
il solo -p:Version non ne deriverebbe nessuno. Utilities/AppInfo li legge a
runtime, e vederne divergere uno significa un titolo finestra che mente.
-->
<Target Name="Pubblica" DependsOnTargets="DeterminaVersione">
<Message Importance="High" Text="== Pubblicazione dell'eseguibile ($(V)) ==" />
<Exec WorkingDirectory="$(Radice)" <Exec WorkingDirectory="$(Radice)"
EnvironmentVariables="$(AmbientePulito)" EnvironmentVariables="$(AmbientePulito)"
Command="dotnet publish &quot;$(Csproj)&quot; -c Release -r win-x64 --nologo -v q --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:PublishReadyToRun=true -p:PublishTrimmed=false -o &quot;$(CartellaPubblicazione)&quot;" /> Command="dotnet publish &quot;$(Csproj)&quot; -c Release -r win-x64 --nologo -v q --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:PublishReadyToRun=true -p:PublishTrimmed=false -p:Version=$(V) -p:AssemblyVersion=$(V).0 -p:FileVersion=$(V).0 -p:InformationalVersion=$(V) -o &quot;$(CartellaPubblicazione)&quot;" />
<Error Condition="!Exists('$(CartellaPubblicazione)\AutoBidder.exe')" <Error Condition="!Exists('$(CartellaPubblicazione)\AutoBidder.exe')"
Text="Pubblicazione fallita: AutoBidder.exe non trovato." /> Text="Pubblicazione fallita: AutoBidder.exe non trovato." />
@@ -366,26 +432,17 @@
<!-- ═════════════════════ Pacchetto ═════════════════════ --> <!-- ═════════════════════ Pacchetto ═════════════════════ -->
<!-- <!--
L'ordine conta: prima si verifica, POI si scrive la versione. L'ordine conta: si verifica, si costruisce, e il tag si crea per ultimo.
Il contrario sembra piu' naturale — decidi il numero, poi costruisci — ma Il contrario sembra piu' naturale — decidi il numero, poi costruisci — ma
lascia il .csproj alzato quando i test falliscono, e il tentativo successivo lascia dietro un tag quando qualcosa va storto, e il tentativo successivo
riparte da li'. Un giro andato male e il numero e' salito lo stesso, senza riparte da li'. Un giro andato male e il numero e' salito lo stesso, senza
che sia mai esistito un pacchetto con quella versione. che sia mai esistito un pacchetto con quella versione. Taggando in fondo,
ogni tag corrisponde a un installatore che esiste davvero.
--> -->
<Target Name="Pacchetto"> <Target Name="Pacchetto" DependsOnTargets="Verifica;DeterminaVersione;Pubblica">
<CallTarget Targets="Verifica" Condition="'$(SaltaVerifica)' != 'true'" />
<CallTarget Targets="ImpostaVersione" />
<CallTarget Targets="Pubblica" />
<Message Importance="High" Text="== Creazione dell'installatore ==" /> <Message Importance="High" Text="== Creazione dell'installatore ==" />
<!-- CallTarget non restituisce le proprieta' impostate dal target chiamato:
la versione si rilegge dal .csproj, che ImpostaVersione ha appena scritto. -->
<TrovaVersione Csproj="$(Csproj)" SoloLettura="true">
<Output TaskParameter="Attuale" PropertyName="VersioneEffettiva" />
</TrovaVersione>
<TrovaInnoSetup> <TrovaInnoSetup>
<Output TaskParameter="Percorso" PropertyName="Iscc" /> <Output TaskParameter="Percorso" PropertyName="Iscc" />
</TrovaInnoSetup> </TrovaInnoSetup>
@@ -393,47 +450,79 @@
<MakeDir Directories="$(CartellaPacchetti)" /> <MakeDir Directories="$(CartellaPacchetti)" />
<Exec WorkingDirectory="$(MSBuildThisFileDirectory)" <Exec WorkingDirectory="$(MSBuildThisFileDirectory)"
Command="&quot;$(Iscc)&quot; /Qp &quot;/DAppVersion=$(VersioneEffettiva)&quot; &quot;/DSourceExe=$(CartellaPubblicazione)\AutoBidder.exe&quot; &quot;/DOutputDir=$(CartellaPacchetti)&quot; &quot;$(Iss)&quot;" /> Command="&quot;$(Iscc)&quot; /Qp &quot;/DAppVersion=$(V)&quot; &quot;/DSourceExe=$(CartellaPubblicazione)\AutoBidder.exe&quot; &quot;/DOutputDir=$(CartellaPacchetti)&quot; &quot;$(Iss)&quot;" />
<PropertyGroup> <PropertyGroup>
<Setup>$(CartellaPacchetti)\AutoBidder-$(VersioneEffettiva)-setup.exe</Setup> <Setup>$(CartellaPacchetti)\AutoBidder-$(V)-setup.exe</Setup>
</PropertyGroup> </PropertyGroup>
<Error Condition="!Exists('$(Setup)')" Text="Installatore non trovato: $(Setup)" /> <Error Condition="!Exists('$(Setup)')" Text="Installatore non trovato: $(Setup)" />
<!-- Adesso: il pacchetto c'e', il tag puo' esistere. -->
<CallTarget Targets="CreaTag" />
<Message Importance="High" Text=" " /> <Message Importance="High" Text=" " />
<Message Importance="High" Text="Pacchetto pronto:" /> <Message Importance="High" Text="Pacchetto pronto:" />
<Message Importance="High" Text=" $(Setup)" /> <Message Importance="High" Text=" $(Setup)" />
</Target> </Target>
<Target Name="ImpostaVersione"> <!-- ═════════════════════ Versione e tag ═════════════════════ -->
<TrovaVersione Csproj="$(Csproj)" Richiesta="$(Versione)">
<Output TaskParameter="Attuale" PropertyName="VersionePrecedente" />
<Output TaskParameter="Effettiva" PropertyName="VersioneEffettiva" />
</TrovaVersione>
<ScriviVersione Csproj="$(Csproj)" Versione="$(VersioneEffettiva)" <Target Name="DeterminaVersione">
Condition="'$(VersioneEffettiva)' != '$(VersionePrecedente)'" /> <!-- Nessuno dei due comandi fallisce mai: senza tag l'uscita e' vuota, e
basta. `git describe` invece esce in errore, e qui non serve. -->
<Exec Command="git tag --points-at HEAD" WorkingDirectory="$(Radice)"
ConsoleToMSBuild="true" StandardOutputImportance="low">
<Output TaskParameter="ConsoleOutput" PropertyName="TagSuHead" />
</Exec>
<Exec Command="git tag --list v*" WorkingDirectory="$(Radice)"
ConsoleToMSBuild="true" StandardOutputImportance="low">
<Output TaskParameter="ConsoleOutput" PropertyName="TagEsistenti" />
</Exec>
<VersioneDaTag TagsHead="$(TagSuHead)" TagsTutti="$(TagEsistenti)"
Richiesta="$(Versione)" Csproj="$(Csproj)">
<Output TaskParameter="Versione" PropertyName="V" />
<Output TaskParameter="Tag" PropertyName="Tag" />
<Output TaskParameter="DaCreare" PropertyName="TagDaCreare" />
</VersioneDaTag>
</Target>
<Target Name="CreaTag" Condition="'$(TagDaCreare)' == 'true'">
<!-- Solo le modifiche ai file gia' tracciati: un appunto non versionato
accanto al progetto non cambia cosa viene compilato. -->
<Exec Command="git status --porcelain --untracked-files=no" WorkingDirectory="$(Radice)"
ConsoleToMSBuild="true" StandardOutputImportance="low">
<Output TaskParameter="ConsoleOutput" PropertyName="AlberoSporco" />
</Exec>
<Error Condition="'$(AlberoSporco)' != '' AND '$(ConsentiModifiche)' != 'true'"
Text="Ci sono modifiche non committate: il tag $(Tag) indicherebbe uno stato che non e' ricostruibile.%0ACommitta prima di rilasciare, oppure rilancia con -p:ConsentiModifiche=true se sai cosa stai facendo.%0A%0A$(AlberoSporco)" />
<Exec Command="git tag -a $(Tag) -m &quot;AutoBidder $(V)&quot;" WorkingDirectory="$(Radice)"
StandardOutputImportance="low" StandardErrorImportance="low" />
<Message Importance="High" Text=" tag $(Tag) creato" />
</Target> </Target>
<!-- ═════════════════════ Rilascio ═════════════════════ --> <!-- ═════════════════════ Rilascio ═════════════════════ -->
<Target Name="Rilascia" DependsOnTargets="Pacchetto"> <!-- Prima di tutto il resto: un token mancante non deve costare due minuti di
<Message Importance="High" Text="== Pubblicazione su Gitea ==" /> compilazione per poi fermarsi all'ultimo passo. -->
<Target Name="ConfigGitea">
<TrovaVersione Csproj="$(Csproj)" SoloLettura="true">
<Output TaskParameter="Attuale" PropertyName="V" />
</TrovaVersione>
<LeggiConfigGitea Percorso="$(MSBuildThisFileDirectory)gitea.json"> <LeggiConfigGitea Percorso="$(MSBuildThisFileDirectory)gitea.json">
<Output TaskParameter="Url" PropertyName="GUrl" /> <Output TaskParameter="Url" PropertyName="GUrl" />
<Output TaskParameter="Owner" PropertyName="GOwner" /> <Output TaskParameter="Owner" PropertyName="GOwner" />
<Output TaskParameter="Repo" PropertyName="GRepo" /> <Output TaskParameter="Repo" PropertyName="GRepo" />
<Output TaskParameter="Token" PropertyName="GToken" /> <Output TaskParameter="Token" PropertyName="GToken" />
</LeggiConfigGitea> </LeggiConfigGitea>
</Target>
<Target Name="Rilascia" DependsOnTargets="ConfigGitea;Pacchetto">
<Message Importance="High" Text="== Pubblicazione su Gitea ==" />
<PropertyGroup> <PropertyGroup>
<Tag>v$(V)</Tag>
<Api>$(GUrl)/api/v1/repos/$(GOwner)/$(GRepo)</Api> <Api>$(GUrl)/api/v1/repos/$(GOwner)/$(GRepo)</Api>
<Tmp>$([System.IO.Path]::GetTempPath())AutoBidder.Rilascio</Tmp> <Tmp>$([System.IO.Path]::GetTempPath())AutoBidder.Rilascio</Tmp>
<CurlCfg>$(Tmp)\curl.cfg</CurlCfg> <CurlCfg>$(Tmp)\curl.cfg</CurlCfg>
@@ -448,11 +537,9 @@
<WriteLinesToFile File="$(CurlCfg)" Overwrite="true" <WriteLinesToFile File="$(CurlCfg)" Overwrite="true"
Lines="header = &quot;Authorization: token $(GToken)&quot;" /> Lines="header = &quot;Authorization: token $(GToken)&quot;" />
<!-- Il tag e' locale: senza remoto la release lo crea da se', quindi un <!-- Il tag esiste gia' in locale (l'ha creato Pacchetto, o c'era prima).
fallimento qui non deve fermare il rilascio. --> Qui si prova solo a spingerlo: se il remoto non risponde la release lo
<Exec Command="git tag -a $(Tag) -m &quot;AutoBidder $(V)&quot;" crea da se', quindi un fallimento non deve fermare il rilascio. -->
WorkingDirectory="$(Radice)" ContinueOnError="true"
StandardOutputImportance="low" StandardErrorImportance="low" />
<Exec Command="git push --tags" WorkingDirectory="$(Radice)" ContinueOnError="true" <Exec Command="git push --tags" WorkingDirectory="$(Radice)" ContinueOnError="true"
StandardOutputImportance="low" StandardErrorImportance="low" /> StandardOutputImportance="low" StandardErrorImportance="low" />