diff --git a/ln.build/pipeline/ReleaseCommand.cs b/ln.build/pipeline/ReleaseCommand.cs index 5711171..7181474 100644 --- a/ln.build/pipeline/ReleaseCommand.cs +++ b/ln.build/pipeline/ReleaseCommand.cs @@ -38,7 +38,14 @@ namespace ln.build.pipeline } stage.CommandEnvironment.Logger.Log(LogLevel.INFO, "Adding {0} to release as {1}", localPath, remoteFileName); - release.AddAttachement(localPath, remoteFileName); + Attachment attachment = release.CreateOrReplaceAttachment( localPath, remoteFileName ); + + // Cleanup attachments + foreach (Attachment b in release.GetAttachments()) + { + if (!b.Equals(attachment) && b.Name.Equals(attachment.Name)) + b.Delete(); + } } } else { diff --git a/ln.build/repositories/Release.cs b/ln.build/repositories/Release.cs index 4372f1d..601a9d2 100644 --- a/ln.build/repositories/Release.cs +++ b/ln.build/repositories/Release.cs @@ -1,6 +1,7 @@ using System; using System.Net.Http.Headers; +using System.Runtime; namespace ln.build.repositories { @@ -16,27 +17,39 @@ namespace ln.build.repositories public abstract Repository Repository { get; } - public abstract Attachement[] GetAttachements(); + public abstract Attachment[] GetAttachments(); - public abstract void AddAttachement(string localPath,string remoteFilename); + public abstract Attachment CreateOrReplaceAttachment(string localPath, string remoteFileName); - - - public class Attachement + public virtual Attachment FindAttachmentByName(string name) { - public Release Release { get; set; } - public int Id { get; set; } = -1; - public string Name { get; set; } - public Guid UUID { get; set; } - - public string DownloadURL { get; set; } - - public Attachement(Release release) - { - Release = release; - } - + foreach (Attachment attachment in GetAttachments()) + if (attachment.Name.Equals(name)) + return attachment; + return null; } + } + public abstract class Attachment + { + public abstract Release Release { get; } + public abstract int Id { get; set; } + public abstract string Name { get; set; } + + public abstract string DownloadURL { get; set; } + + public Attachment() + { + } + + public abstract void Create(string localPath); + public abstract void Delete(); + + + public override bool Equals(object obj) => (obj is Attachment attachment) && Id.Equals(attachment.Id); + public override int GetHashCode() => Id.GetHashCode(); + } + + } \ No newline at end of file diff --git a/ln.build/repositories/gitea/GiteaRelease.cs b/ln.build/repositories/gitea/GiteaRelease.cs index b086a7f..7fd5e29 100644 --- a/ln.build/repositories/gitea/GiteaRelease.cs +++ b/ln.build/repositories/gitea/GiteaRelease.cs @@ -1,9 +1,12 @@ using System; +using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Http; +using System.Reflection.Emit; using ln.json; +using ln.json.attributes; using ln.type; namespace ln.build.repositories.gitea @@ -26,23 +29,85 @@ namespace ln.build.repositories.gitea IsPreRelease = (bool)jsonRelease["prerelease"].ToNative(); } - public override void AddAttachement(string localPath, string remoteFileName) + public override Attachment CreateOrReplaceAttachment(string localPath, string remoteFileName) + { + Attachment attachment = FindAttachmentByName(remoteFileName) ?? new GiteaAttachment(this){ Name = remoteFileName, }; + attachment.Create(localPath); + return attachment; + } + + public override Attachment[] GetAttachments() + { + if (HttpStatusCode.OK == GiteaRepository.Client.GetJson(out JSONValue jsonAssets, "repos", GiteaRepository.Owner, GiteaRepository.Name, "releases", Id.ToString(), "assets" )) + { + List attachments = new List(); + + foreach (JSONObject jsonAsset in (jsonAssets as JSONArray).Children) + attachments.Add(new GiteaAttachment(this, jsonAsset)); + + return attachments.ToArray(); + } + return null; + } + } + + public class GiteaAttachment : Attachment + { + public override Release Release => GiteaRelease; + public GiteaRelease GiteaRelease { get; } + + int id = -1; + string downloadURL; + + public override int Id { get => id; set => throw new NotImplementedException(); } + public override string Name { get; set; } + public override string DownloadURL { get => downloadURL; set => throw new NotImplementedException(); } + + public GiteaAttachment(GiteaRelease giteaRelease) + { + GiteaRelease = giteaRelease; + } + public GiteaAttachment(GiteaRelease giteaRelease,JSONObject jsonAttachment) :this(giteaRelease) + { + LoadJson(jsonAttachment); + } + + private void LoadJson(JSONObject jsonAttachment) + { + id = (int)(long)jsonAttachment["id"].ToNative(); + Name = jsonAttachment["name"].ToNative().ToString(); + downloadURL = jsonAttachment["browser_download_url"].ToNative().ToString(); + } + + public override void Delete() + { + if (id != -1) + { + if (HttpStatusCode.NoContent != GiteaRelease.GiteaRepository.Client.Delete("repos", GiteaRelease.GiteaRepository.Owner, GiteaRelease.GiteaRepository.Name, "releases", GiteaRelease.Id.ToString(), "assets", id.ToString())) + throw new Exception(String.Format("could not delete attachment {0}/{1}", GiteaRelease.Id, id)); + + id = -1; + } + } + + public override void Create(string localPath) { using (FileStream fs = new FileStream(localPath,FileMode.Open)) { StreamContent attachmentBytes = new StreamContent(fs); MultipartFormDataContent formDataContent = new MultipartFormDataContent(); - formDataContent.Add(attachmentBytes, "attachment", remoteFileName); - if (HttpStatusCode.Created != GiteaRepository.Client.PostContent(formDataContent,out JSONValue response, "repos", GiteaRepository.Owner, GiteaRepository.Name, "releases", Id.ToString(), String.Format("assets?name={0}", remoteFileName))) + formDataContent.Add(attachmentBytes, "attachment", Name); + if (HttpStatusCode.Created != GiteaRelease.GiteaRepository.Client.PostContent(formDataContent,out JSONValue response, "repos", GiteaRelease.GiteaRepository.Owner, GiteaRelease.GiteaRepository.Name, "releases", GiteaRelease.Id.ToString(), string.Format("assets?name={0}", Name))) { throw new Exception(String.Format("could not create attachment to release: {0}", localPath)); } + + if (id != -1) + Delete(); + + LoadJson(response as JSONObject); } } - - public override Attachement[] GetAttachements() - { - throw new System.NotImplementedException(); - } } + } \ No newline at end of file