mirror of
https://git.stillkill.net/Stillkill/GiteaPublish.git
synced 2026-10-22 05:32:18 +01:00
Compare commits
7
Commits
bd1478bca1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21be87d8ea | ||
|
|
238898057a | ||
|
|
2104b52ab2 | ||
|
|
5a74ab9587 | ||
|
|
0060e11d73 | ||
|
|
6e87b13b39 | ||
|
|
79cb442d35 |
No files matched your search
File renamed without changes.
@@ -0,0 +1,62 @@
|
||||
name: Publish Debian Package
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-and-publish:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 10.0.x
|
||||
|
||||
- name: Build GiteaPublish Tool
|
||||
run: |
|
||||
dotnet publish GiteaPublish/GiteaPublish.csproj -c Release -r linux-x64 --self-contained \
|
||||
-p:PublishSingleFile=true \
|
||||
-p:PublishReadyToRun=true \
|
||||
-p:UseAppHost=true \
|
||||
-o ./publish-tool
|
||||
|
||||
- name: Get application version
|
||||
id: get_version
|
||||
run: |
|
||||
VERSION=$(dotnet run -v q --property WarningLevel=0 --project GiteaPublish -- --version)
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Application version: $VERSION"
|
||||
|
||||
- name: Build Debian Package
|
||||
run: |
|
||||
sed -i "s/<PKG-VER>/${{ steps.get_version.outputs.version }}/g" debian/control
|
||||
mkdir -p package/usr/bin
|
||||
cp ./publish-tool/GiteaPublish package/usr/bin/gitea-publish
|
||||
mkdir -p package/DEBIAN
|
||||
cp debian/control package/DEBIAN/
|
||||
chmod 755 package/usr/bin/gitea-publish
|
||||
chmod 755 package/DEBIAN
|
||||
chmod 644 package/DEBIAN/control
|
||||
dpkg-deb --build package gitea-publish_${{ steps.get_version.outputs.version }}_amd64.deb
|
||||
|
||||
- name: Publish to Gitea
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
GITEA_USERNAME: ${{ github.actor }}
|
||||
run: |
|
||||
curl --user ${{ secrets.USERNAME }}:${{ secrets.PASSWORD }} \
|
||||
--upload-file gitea-publish_${{ steps.get_version.outputs.version }}_amd64.deb \
|
||||
https://git.stillkill.net/api/packages/stillkill/debian/pool/bionic/main/upload
|
||||
#./publish-tool/GiteaPublish package debian publish \
|
||||
# --username "${GITEA_USERNAME}" \
|
||||
# --password "${GITEA_TOKEN}" \
|
||||
# --owner "${{ github.repository_owner }}" \
|
||||
# --distribution "stable" \
|
||||
# --component "main" \
|
||||
# --file "gitea-publish_${{ steps.get_version.outputs.version }}_amd64.deb" \
|
||||
# --base-url "${{ github.server_url }}"
|
||||
@@ -0,0 +1,90 @@
|
||||
using GiteaPublish.Gitea;
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace GiteaPublish.Commands.Package;
|
||||
|
||||
public class PackageDeleteDebianCommand : AsyncCommand<PackageDeleteDebianCommand.DeleteDebianSettings>
|
||||
{
|
||||
private readonly DebianPackageRepo _packageRepo;
|
||||
private readonly IAnsiConsole _console;
|
||||
|
||||
public PackageDeleteDebianCommand(DebianPackageRepo packageRepo, IAnsiConsole console)
|
||||
{
|
||||
_packageRepo = packageRepo;
|
||||
_console = console;
|
||||
}
|
||||
|
||||
public override async Task<int> ExecuteAsync(CommandContext context, DeleteDebianSettings settings, CancellationToken cancellationToken)
|
||||
{
|
||||
_packageRepo.SetAuthentication(settings.GetAuth());
|
||||
|
||||
bool success = await _packageRepo.DeletePackageAsync(
|
||||
settings.Owner,
|
||||
settings.Distribution,
|
||||
settings.Component,
|
||||
settings.PackageName,
|
||||
settings.PackageVersion,
|
||||
settings.Architecture,
|
||||
settings.BaseUrl);
|
||||
|
||||
if (success)
|
||||
{
|
||||
_console.MarkupLine("[green]Debian package deleted successfully![/]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
_console.MarkupLine("[red]Failed to delete Debian package.[/]");
|
||||
return 1;
|
||||
}
|
||||
|
||||
public override ValidationResult Validate(CommandContext context, DeleteDebianSettings settings)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(settings.Owner))
|
||||
return ValidationResult.Error("Owner is required.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(settings.Distribution))
|
||||
return ValidationResult.Error("Distribution is required.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(settings.Component))
|
||||
return ValidationResult.Error("Component is required.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(settings.PackageName))
|
||||
return ValidationResult.Error("Package name is required.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(settings.PackageVersion))
|
||||
return ValidationResult.Error("Package version is required.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(settings.Architecture))
|
||||
return ValidationResult.Error("Architecture is required.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(settings.AuthFile))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(settings.Username))
|
||||
return ValidationResult.Error("Username is required when --auth-file is not used.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(settings.Password))
|
||||
return ValidationResult.Error("Password is required when --auth-file is not used.");
|
||||
}
|
||||
|
||||
return ValidationResult.Success();
|
||||
}
|
||||
|
||||
public sealed class DeleteDebianSettings : PackageSettings
|
||||
{
|
||||
[CommandOption("-d|--distribution <DISTRIBUTION>", isRequired: true)]
|
||||
public string Distribution { get; init; } = string.Empty;
|
||||
|
||||
[CommandOption("-c|--component <COMPONENT>", isRequired: true)]
|
||||
public string Component { get; init; } = string.Empty;
|
||||
|
||||
[CommandOption("-p|--package-name <PACKAGE_NAME>", isRequired: true)]
|
||||
public string PackageName { get; init; } = string.Empty;
|
||||
|
||||
[CommandOption("-v|--package-version <PACKAGE_VERSION>", isRequired: true)]
|
||||
public string PackageVersion { get; init; } = string.Empty;
|
||||
|
||||
[CommandOption("-a|--architecture <ARCHITECTURE>", isRequired: true)]
|
||||
public string Architecture { get; init; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using GiteaPublish.Gitea;
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace GiteaPublish.Commands.Package;
|
||||
|
||||
|
||||
public class PackagePublishDebianCommand : AsyncCommand<PackagePublishDebianCommand.PublishDebianSettings>
|
||||
{
|
||||
private readonly DebianPackageRepo _packageRepo;
|
||||
private readonly IAnsiConsole _console;
|
||||
|
||||
public PackagePublishDebianCommand(DebianPackageRepo packageRepo, IAnsiConsole console)
|
||||
{
|
||||
_packageRepo = packageRepo;
|
||||
_console = console;
|
||||
}
|
||||
|
||||
public override async Task<int> ExecuteAsync(
|
||||
CommandContext context,
|
||||
PublishDebianSettings settings,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
_packageRepo.SetAuthentication(settings.GetAuth());
|
||||
|
||||
bool success = await _packageRepo.PublishPackageAsync(
|
||||
settings.Owner,
|
||||
settings.Distribution,
|
||||
settings.Component,
|
||||
settings.File,
|
||||
settings.BaseUrl);
|
||||
|
||||
if (success)
|
||||
{
|
||||
_console.MarkupLine("[green]Debian package published successfully![/]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
_console.MarkupLine("[red]Failed to publish Debian package.[/]");
|
||||
return 1;
|
||||
}
|
||||
|
||||
public override ValidationResult Validate(CommandContext context, PublishDebianSettings settings)
|
||||
{
|
||||
if (!File.Exists(settings.File))
|
||||
return ValidationResult.Error($"File '{settings.File}' does not exist.");
|
||||
|
||||
if (!settings.File.EndsWith(".deb", StringComparison.OrdinalIgnoreCase))
|
||||
return ValidationResult.Error("File must be a Debian package ending with '.deb'.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(settings.Owner))
|
||||
return ValidationResult.Error("Owner is required.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(settings.Distribution))
|
||||
return ValidationResult.Error("Distribution is required.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(settings.Component))
|
||||
return ValidationResult.Error("Component is required.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(settings.AuthFile))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(settings.Username))
|
||||
return ValidationResult.Error("Username is required when --auth-file is not used.");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(settings.Password))
|
||||
return ValidationResult.Error("Password is required when --auth-file is not used.");
|
||||
}
|
||||
|
||||
return ValidationResult.Success();
|
||||
}
|
||||
|
||||
public sealed class PublishDebianSettings : PackageSettings
|
||||
{
|
||||
[CommandOption("-f|--file <FILE>", isRequired: true)]
|
||||
public required string File { get; init; }
|
||||
|
||||
[CommandOption("-d|--distribution <DISTRIBUTION>", isRequired: true)]
|
||||
public string Distribution { get; init; } = string.Empty;
|
||||
|
||||
[CommandOption("-c|--component <COMPONENT>", isRequired: true)]
|
||||
public string Component { get; init; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System.Net.Http.Headers;
|
||||
using Spectre.Console;
|
||||
|
||||
namespace GiteaPublish.Gitea;
|
||||
|
||||
public class DebianPackageRepo(HttpClient httpClient, IAnsiConsole ansiConsole)
|
||||
{
|
||||
private BasicAuthModel BasicAuth { get; set; } = new BasicAuthModel();
|
||||
|
||||
public async Task<bool> PublishPackageAsync(string owner, string distribution, string component, string filePath,
|
||||
string baseUrl)
|
||||
{
|
||||
httpClient.BaseAddress = new Uri(baseUrl.TrimEnd('/'));
|
||||
ansiConsole.MarkupLine(
|
||||
$"[blue]Publishing Debian package {filePath.EscapeMarkup()} to {owner.EscapeMarkup()}/{distribution.EscapeMarkup()}/{component.EscapeMarkup()}...[/]");
|
||||
HttpRequestMessage request = new(
|
||||
HttpMethod.Put,
|
||||
$"/api/packages/{Uri.EscapeDataString(owner)}/debian/pool/{Uri.EscapeDataString(distribution)}/{Uri.EscapeDataString(component)}/upload");
|
||||
request.Content = new ByteArrayContent(await File.ReadAllBytesAsync(filePath));
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", BasicAuth.AuthHeader);
|
||||
|
||||
HttpResponseMessage response = await httpClient.SendAsync(request);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
return true;
|
||||
|
||||
ansiConsole.MarkupLine($"[red]Failed to publish Debian package: {response.StatusCode}[/]");
|
||||
ansiConsole.MarkupLine($"[red]{(await response.Content.ReadAsStringAsync()).EscapeMarkup()}[/]");
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> DeletePackageAsync(string owner, string distribution, string component, string packageName,
|
||||
string packageVersion, string architecture, string baseUrl)
|
||||
{
|
||||
httpClient.BaseAddress = new Uri(baseUrl.TrimEnd('/'));
|
||||
|
||||
ansiConsole.MarkupLine(
|
||||
$"[blue]Deleting Debian package {packageName} {packageVersion} [{architecture}] from {owner}/{distribution}/{component}...[/]");
|
||||
|
||||
HttpRequestMessage request = new(
|
||||
HttpMethod.Delete,
|
||||
$"/api/packages/{Uri.EscapeDataString(owner)}/debian/pool/{Uri.EscapeDataString(distribution)}/{Uri.EscapeDataString(component)}/{Uri.EscapeDataString(packageName)}/{Uri.EscapeDataString(packageVersion)}/{Uri.EscapeDataString(architecture)}");
|
||||
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", BasicAuth.AuthHeader);
|
||||
|
||||
HttpResponseMessage response = await httpClient.SendAsync(request);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
return true;
|
||||
|
||||
ansiConsole.MarkupLine($"[red]Failed to delete Debian package: {response.StatusCode}[/]");
|
||||
ansiConsole.MarkupLine($"[red]{(await response.Content.ReadAsStringAsync()).EscapeMarkup()}[/]");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetAuthentication(BasicAuthModel basicAuth)
|
||||
{
|
||||
BasicAuth = basicAuth;
|
||||
ansiConsole.MarkupLine("[green]Authentication set.[/]");
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>1.0.0.14</Version>
|
||||
<Version>1.0.1.4</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
+15
-3
@@ -15,6 +15,7 @@ class Program
|
||||
{
|
||||
ServiceCollection services = new();
|
||||
services.AddSingleton<IPackageRepo, ArchPackageRepo>();
|
||||
services.AddSingleton<DebianPackageRepo>();
|
||||
services.AddSingleton(CreateHttpClient());
|
||||
services.AddSingleton<ReleaseService>();
|
||||
TypeRegistrar registrar = new TypeRegistrar(services);
|
||||
@@ -34,8 +35,19 @@ class Program
|
||||
.WithExample("package arch publish --username <username> --password <password or token> " +
|
||||
"-o <repo owner> -r <repo name> -f <package file> -b <base url>");
|
||||
|
||||
// archConfig.AddCommand<PackageDeleteArchCommand>("delete")
|
||||
// .WithDescription("Deletes an Arch package from a Gitea repository");
|
||||
packageConfig.AddBranch("debian", debianConfig =>
|
||||
{
|
||||
debianConfig.AddCommand<PackagePublishDebianCommand>("publish")
|
||||
.WithDescription("Publish a Debian package to a Gitea repository")
|
||||
.WithExample("package debian publish --username <username> --password <password or token> " +
|
||||
"-o <owner> -d <distribution> -c <component> -f <package.deb> -b <base url>");
|
||||
|
||||
debianConfig.AddCommand<PackageDeleteDebianCommand>("delete")
|
||||
.WithDescription("Delete a Debian package from a Gitea repository")
|
||||
.WithExample("package debian delete --username <username> --password <password or token> " +
|
||||
"-o <owner> -d <distribution> -c <component> " +
|
||||
"-p <package name> -v <package version> -a <architecture> -b <base url>");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -64,7 +76,7 @@ class Program
|
||||
private static HttpClient CreateHttpClient()
|
||||
{
|
||||
HttpClient httpClient = new();
|
||||
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd($"GiteaPublish/{ApplicationVersion.Version}");
|
||||
//httpClient.DefaultRequestHeaders.UserAgent.ParseAdd($"GiteaPublish/{ApplicationVersion.Version}");
|
||||
return httpClient;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
Package: gitea-publish
|
||||
Version: <PKG-VER>
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
Maintainer: Stillkill <stillkill@example.com>
|
||||
Description: Tool to publish packages to Gitea
|
||||
Reference in new issue
Block a user