2026-01-05 12:57:37 +01:00
|
|
|
package cmd
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
"path"
|
2026-01-05 12:57:37 +01:00
|
|
|
"path/filepath"
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"code.gitea.io/sdk/gitea"
|
feat: v0.3.0a — add api command, pr diff/comment/review, structured errors
New commands:
- fgj api: raw REST API passthrough with field inference and path interpolation
- fgj pr diff: view PR diffs with color, --name-only, --stat
- fgj pr comment: add comments to pull requests
- fgj pr review: approve, request changes, or comment on PRs
Agentic enhancements:
- --json-errors flag for structured JSON error output on stderr
- APIError type wrapping HTTP status codes for machine consumption
- Error codes: auth_required, not_found, api_error, invalid_input, etc.
Docs updated for forgejo.zerova.net/sid/fgj-sid fork.
2026-03-21 21:50:24 -06:00
|
|
|
"forgejo.zerova.net/sid/fgj-sid/internal/api"
|
|
|
|
|
"forgejo.zerova.net/sid/fgj-sid/internal/config"
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
"forgejo.zerova.net/sid/fgj-sid/internal/text"
|
2026-01-05 12:57:37 +01:00
|
|
|
"github.com/spf13/cobra"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var releaseCmd = &cobra.Command{
|
|
|
|
|
Use: "release",
|
|
|
|
|
Aliases: []string{"releases"},
|
|
|
|
|
Short: "Manage releases",
|
|
|
|
|
Long: "Create, view, list, upload assets, and delete releases.",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var releaseListCmd = &cobra.Command{
|
|
|
|
|
Use: "list",
|
|
|
|
|
Short: "List releases",
|
|
|
|
|
Long: "List releases in a repository.",
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Example: ` # List releases
|
|
|
|
|
fgj release list
|
|
|
|
|
|
|
|
|
|
# List only draft releases
|
|
|
|
|
fgj release list --draft
|
|
|
|
|
|
|
|
|
|
# Output as JSON with a custom limit
|
|
|
|
|
fgj release list --json --limit 10`,
|
|
|
|
|
RunE: runReleaseList,
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var releaseViewCmd = &cobra.Command{
|
|
|
|
|
Use: "view <tag|latest>",
|
|
|
|
|
Short: "View a release",
|
|
|
|
|
Long: "Display detailed information about a release.",
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Example: ` # View a release by tag
|
|
|
|
|
fgj release view v1.0.0
|
|
|
|
|
|
|
|
|
|
# View the latest release
|
|
|
|
|
fgj release view latest
|
|
|
|
|
|
|
|
|
|
# Open in browser
|
|
|
|
|
fgj release view v1.0.0 --web
|
|
|
|
|
|
|
|
|
|
# Output as JSON
|
|
|
|
|
fgj release view v1.0.0 --json`,
|
|
|
|
|
Args: cobra.ExactArgs(1),
|
|
|
|
|
RunE: runReleaseView,
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var releaseCreateCmd = &cobra.Command{
|
|
|
|
|
Use: "create <tag> [files...]",
|
|
|
|
|
Short: "Create a release",
|
|
|
|
|
Long: "Create a new release and optionally upload assets.",
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Example: ` # Create a release
|
|
|
|
|
fgj release create v1.0.0
|
|
|
|
|
|
|
|
|
|
# Create with title and notes
|
|
|
|
|
fgj release create v1.0.0 -t "First stable release" -n "Bug fixes and improvements"
|
|
|
|
|
|
|
|
|
|
# Create a draft prerelease with assets
|
|
|
|
|
fgj release create v2.0.0-rc1 --draft --prerelease dist/*.tar.gz
|
|
|
|
|
|
|
|
|
|
# Create from release notes file
|
|
|
|
|
fgj release create v1.0.0 -F CHANGELOG.md`,
|
|
|
|
|
Args: cobra.MinimumNArgs(1),
|
|
|
|
|
RunE: runReleaseCreate,
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var releaseUploadCmd = &cobra.Command{
|
|
|
|
|
Use: "upload <tag|latest> <files...>",
|
|
|
|
|
Short: "Upload release assets",
|
|
|
|
|
Long: "Upload assets to an existing release.",
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Example: ` # Upload assets to a release
|
|
|
|
|
fgj release upload v1.0.0 dist/app-linux-amd64 dist/app-darwin-arm64
|
|
|
|
|
|
|
|
|
|
# Upload to the latest release, overwriting existing assets
|
|
|
|
|
fgj release upload latest build/output.zip --clobber`,
|
|
|
|
|
Args: cobra.MinimumNArgs(2),
|
|
|
|
|
RunE: runReleaseUpload,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var releaseDownloadCmd = &cobra.Command{
|
|
|
|
|
Use: "download <tag>",
|
|
|
|
|
Short: "Download release assets",
|
|
|
|
|
Long: "Download assets from a release.",
|
|
|
|
|
Example: ` # Download all assets from a release
|
|
|
|
|
fgj release download v1.0.0
|
|
|
|
|
|
|
|
|
|
# Download to a specific directory
|
|
|
|
|
fgj release download v1.0.0 -D ./downloads
|
|
|
|
|
|
|
|
|
|
# Download a specific asset by name pattern
|
|
|
|
|
fgj release download v1.0.0 -p "*.tar.gz"`,
|
|
|
|
|
Args: cobra.ExactArgs(1),
|
|
|
|
|
RunE: runReleaseDownload,
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var releaseDeleteCmd = &cobra.Command{
|
|
|
|
|
Use: "delete <tag|latest>",
|
|
|
|
|
Short: "Delete a release",
|
|
|
|
|
Long: "Delete a release by tag, keeping its Git tag intact.",
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
Example: ` # Delete a release by tag
|
|
|
|
|
fgj release delete v1.0.0
|
|
|
|
|
|
|
|
|
|
# Delete the latest release
|
|
|
|
|
fgj release delete latest
|
|
|
|
|
|
|
|
|
|
# Delete without confirmation
|
|
|
|
|
fgj release delete v1.0.0 -y`,
|
|
|
|
|
Args: cobra.ExactArgs(1),
|
|
|
|
|
RunE: runReleaseDelete,
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
|
rootCmd.AddCommand(releaseCmd)
|
|
|
|
|
releaseCmd.AddCommand(releaseListCmd)
|
|
|
|
|
releaseCmd.AddCommand(releaseViewCmd)
|
|
|
|
|
releaseCmd.AddCommand(releaseCreateCmd)
|
|
|
|
|
releaseCmd.AddCommand(releaseUploadCmd)
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
releaseCmd.AddCommand(releaseDownloadCmd)
|
2026-01-05 12:57:37 +01:00
|
|
|
releaseCmd.AddCommand(releaseDeleteCmd)
|
|
|
|
|
|
|
|
|
|
releaseListCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
|
|
|
|
releaseListCmd.Flags().Bool("draft", false, "Filter by draft status")
|
|
|
|
|
releaseListCmd.Flags().Bool("prerelease", false, "Filter by prerelease status")
|
|
|
|
|
releaseListCmd.Flags().Int("limit", 30, "Maximum number of releases to fetch")
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
addJSONFlags(releaseListCmd, "Output releases as JSON")
|
2026-01-05 12:57:37 +01:00
|
|
|
|
|
|
|
|
releaseViewCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
addJSONFlags(releaseViewCmd, "Output release as JSON")
|
|
|
|
|
releaseViewCmd.Flags().BoolP("web", "w", false, "Open in web browser")
|
2026-01-05 12:57:37 +01:00
|
|
|
|
|
|
|
|
releaseCreateCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
|
|
|
|
releaseCreateCmd.Flags().StringP("title", "t", "", "Release title (defaults to tag)")
|
|
|
|
|
releaseCreateCmd.Flags().StringP("notes", "n", "", "Release notes")
|
|
|
|
|
releaseCreateCmd.Flags().StringP("notes-file", "F", "", "Read release notes from file")
|
|
|
|
|
releaseCreateCmd.Flags().Bool("draft", false, "Create a draft release")
|
|
|
|
|
releaseCreateCmd.Flags().Bool("prerelease", false, "Mark the release as prerelease")
|
|
|
|
|
releaseCreateCmd.Flags().String("target", "", "Target commitish (branch or SHA)")
|
|
|
|
|
|
|
|
|
|
releaseUploadCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
|
|
|
|
releaseUploadCmd.Flags().Bool("clobber", false, "Overwrite assets with the same name")
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
releaseDownloadCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
|
|
|
|
releaseDownloadCmd.Flags().StringP("dir", "D", ".", "Directory to download files into")
|
|
|
|
|
releaseDownloadCmd.Flags().StringP("pattern", "p", "", "Glob pattern to filter assets by name")
|
|
|
|
|
|
2026-01-05 12:57:37 +01:00
|
|
|
releaseDeleteCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
releaseDeleteCmd.Flags().BoolP("yes", "y", false, "Skip confirmation prompt")
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runReleaseList(cmd *cobra.Command, args []string) error {
|
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
|
|
|
|
limit, _ := cmd.Flags().GetInt("limit")
|
|
|
|
|
draftValue, _ := cmd.Flags().GetBool("draft")
|
|
|
|
|
prereleaseValue, _ := cmd.Flags().GetBool("prerelease")
|
|
|
|
|
draftSet := cmd.Flags().Changed("draft")
|
|
|
|
|
prereleaseSet := cmd.Flags().Changed("prerelease")
|
|
|
|
|
|
|
|
|
|
if limit <= 0 {
|
|
|
|
|
return fmt.Errorf("limit must be greater than 0")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
owner, name, err := parseRepo(repo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg, err := config.Load()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-05 12:47:28 +01:00
|
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost())
|
2026-01-05 12:57:37 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pageSize := limit
|
|
|
|
|
if pageSize > 50 {
|
|
|
|
|
pageSize = 50
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
opts := gitea.ListReleasesOptions{}
|
|
|
|
|
if draftSet {
|
|
|
|
|
opts.IsDraft = &draftValue
|
|
|
|
|
}
|
|
|
|
|
if prereleaseSet {
|
|
|
|
|
opts.IsPreRelease = &prereleaseValue
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StartSpinner("Fetching releases...")
|
2026-01-05 12:57:37 +01:00
|
|
|
var releases []*gitea.Release
|
|
|
|
|
for page := 1; len(releases) < limit; page++ {
|
|
|
|
|
opts.ListOptions = gitea.ListOptions{Page: page, PageSize: pageSize}
|
|
|
|
|
batch, _, err := client.ListReleases(owner, name, opts)
|
|
|
|
|
if err != nil {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2026-01-05 12:57:37 +01:00
|
|
|
return fmt.Errorf("failed to list releases: %w", err)
|
|
|
|
|
}
|
|
|
|
|
if len(batch) == 0 {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
releases = append(releases, batch...)
|
|
|
|
|
}
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2026-01-05 12:57:37 +01:00
|
|
|
|
|
|
|
|
if len(releases) > limit {
|
|
|
|
|
releases = releases[:limit]
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if wantJSON(cmd) {
|
|
|
|
|
return outputJSON(cmd, releases)
|
2026-01-18 11:48:08 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-05 12:57:37 +01:00
|
|
|
if len(releases) == 0 {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
fmt.Fprintf(ios.Out, "No releases in %s/%s\n", owner, name)
|
2026-01-05 12:57:37 +01:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
isTTY := ios.IsStdoutTTY()
|
|
|
|
|
tp := ios.NewTablePrinter()
|
|
|
|
|
tp.AddHeader("TAG", "TITLE", "TYPE", "PUBLISHED")
|
2026-01-05 12:57:37 +01:00
|
|
|
for _, rel := range releases {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
published := text.FormatDate(releaseTimestamp(rel), isTTY)
|
|
|
|
|
tp.AddRow(rel.TagName, rel.Title, releaseType(rel), published)
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
return tp.Render()
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runReleaseView(cmd *cobra.Command, args []string) error {
|
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
|
|
|
|
tag := args[0]
|
|
|
|
|
|
|
|
|
|
owner, name, err := parseRepo(repo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg, err := config.Load()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-05 12:47:28 +01:00
|
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost())
|
2026-01-05 12:57:37 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StartSpinner("Fetching release...")
|
2026-01-05 12:57:37 +01:00
|
|
|
release, err := getReleaseByTagOrLatest(client, owner, name, tag)
|
|
|
|
|
if err != nil {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2026-01-05 12:57:37 +01:00
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-18 11:48:08 +01:00
|
|
|
attachments, err := listReleaseAttachments(client, owner, name, release.ID)
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2026-01-18 11:48:08 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if web, _ := cmd.Flags().GetBool("web"); web {
|
|
|
|
|
if release.HTMLURL != "" {
|
|
|
|
|
return ios.OpenInBrowser(release.HTMLURL)
|
|
|
|
|
}
|
|
|
|
|
return fmt.Errorf("release has no HTML URL")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if wantJSON(cmd) {
|
2026-01-18 11:48:08 +01:00
|
|
|
payload := struct {
|
|
|
|
|
Release *gitea.Release `json:"release"`
|
|
|
|
|
Assets []*gitea.Attachment `json:"assets,omitempty"`
|
|
|
|
|
}{
|
|
|
|
|
Release: release,
|
|
|
|
|
Assets: attachments,
|
|
|
|
|
}
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
return outputJSON(cmd, payload)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := ios.StartPager(); err != nil {
|
|
|
|
|
fmt.Fprintf(ios.ErrOut, "warning: failed to start pager: %v\n", err)
|
2026-01-18 11:48:08 +01:00
|
|
|
}
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
defer ios.StopPager()
|
2026-01-18 11:48:08 +01:00
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
cs := ios.ColorScheme()
|
|
|
|
|
isTTY := ios.IsStdoutTTY()
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(ios.Out, "Release %s\n", cs.Bold(release.TagName))
|
|
|
|
|
fmt.Fprintf(ios.Out, "Title: %s\n", release.Title)
|
|
|
|
|
fmt.Fprintf(ios.Out, "Type: %s\n", releaseType(release))
|
2026-01-05 12:57:37 +01:00
|
|
|
if release.Target != "" {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
fmt.Fprintf(ios.Out, "Target: %s\n", release.Target)
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
|
|
|
|
if release.Publisher != nil {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
fmt.Fprintf(ios.Out, "Author: %s\n", release.Publisher.UserName)
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
fmt.Fprintf(ios.Out, "Created: %s\n", text.FormatDate(release.CreatedAt, isTTY))
|
2026-01-05 12:57:37 +01:00
|
|
|
if !release.PublishedAt.IsZero() {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
fmt.Fprintf(ios.Out, "Published: %s\n", text.FormatDate(release.PublishedAt, isTTY))
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
|
|
|
|
if release.HTMLURL != "" {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
fmt.Fprintf(ios.Out, "URL: %s\n", release.HTMLURL)
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
|
|
|
|
if release.Note != "" {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
fmt.Fprintf(ios.Out, "\n%s\n", release.Note)
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(attachments) > 0 {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
fmt.Fprintf(ios.Out, "\nAssets (%d):\n", len(attachments))
|
2026-01-05 12:57:37 +01:00
|
|
|
for _, asset := range attachments {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
fmt.Fprintf(ios.Out, "- %s (%d bytes) %s\n", asset.Name, asset.Size, asset.DownloadURL)
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runReleaseCreate(cmd *cobra.Command, args []string) error {
|
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
|
|
|
|
title, _ := cmd.Flags().GetString("title")
|
|
|
|
|
notes, _ := cmd.Flags().GetString("notes")
|
|
|
|
|
notesFile, _ := cmd.Flags().GetString("notes-file")
|
|
|
|
|
draft, _ := cmd.Flags().GetBool("draft")
|
|
|
|
|
prerelease, _ := cmd.Flags().GetBool("prerelease")
|
|
|
|
|
target, _ := cmd.Flags().GetString("target")
|
|
|
|
|
|
|
|
|
|
if notes != "" && notesFile != "" {
|
|
|
|
|
return fmt.Errorf("use either --notes or --notes-file, not both")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tag := args[0]
|
|
|
|
|
files := args[1:]
|
|
|
|
|
|
|
|
|
|
if notesFile != "" {
|
|
|
|
|
content, err := os.ReadFile(notesFile)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to read notes file: %w", err)
|
|
|
|
|
}
|
|
|
|
|
notes = string(content)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if title == "" {
|
|
|
|
|
title = tag
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
owner, name, err := parseRepo(repo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg, err := config.Load()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-05 12:47:28 +01:00
|
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost())
|
2026-01-05 12:57:37 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StartSpinner("Creating release...")
|
2026-01-05 12:57:37 +01:00
|
|
|
release, _, err := client.CreateRelease(owner, name, gitea.CreateReleaseOption{
|
|
|
|
|
TagName: tag,
|
|
|
|
|
Target: target,
|
|
|
|
|
Title: title,
|
|
|
|
|
Note: notes,
|
|
|
|
|
IsDraft: draft,
|
|
|
|
|
IsPrerelease: prerelease,
|
|
|
|
|
})
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2026-01-05 12:57:37 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to create release: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
cs := ios.ColorScheme()
|
|
|
|
|
fmt.Fprintf(ios.Out, "%s Release created: %s\n", cs.SuccessIcon(), release.TagName)
|
2026-01-05 12:57:37 +01:00
|
|
|
if release.HTMLURL != "" {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
fmt.Fprintf(ios.Out, "View at: %s\n", release.HTMLURL)
|
2026-01-05 12:57:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(files) == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StartSpinner("Uploading assets...")
|
2026-01-05 12:57:37 +01:00
|
|
|
if err := uploadReleaseAssets(client, owner, name, release.ID, files, false); err != nil {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2026-01-05 12:57:37 +01:00
|
|
|
return err
|
|
|
|
|
}
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2026-01-05 12:57:37 +01:00
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
fmt.Fprintf(ios.Out, "%s Uploaded %s\n", cs.SuccessIcon(), text.Pluralize(len(files), "asset"))
|
2026-01-05 12:57:37 +01:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runReleaseUpload(cmd *cobra.Command, args []string) error {
|
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
|
|
|
|
clobber, _ := cmd.Flags().GetBool("clobber")
|
|
|
|
|
|
|
|
|
|
tag := args[0]
|
|
|
|
|
files := args[1:]
|
|
|
|
|
|
|
|
|
|
owner, name, err := parseRepo(repo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg, err := config.Load()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-05 12:47:28 +01:00
|
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost())
|
2026-01-05 12:57:37 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StartSpinner("Fetching release...")
|
2026-01-05 12:57:37 +01:00
|
|
|
release, err := getReleaseByTagOrLatest(client, owner, name, tag)
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2026-01-05 12:57:37 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StartSpinner("Uploading assets...")
|
2026-01-05 12:57:37 +01:00
|
|
|
if err := uploadReleaseAssets(client, owner, name, release.ID, files, clobber); err != nil {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
|
|
|
|
|
cs := ios.ColorScheme()
|
|
|
|
|
fmt.Fprintf(ios.Out, "%s Uploaded %s\n", cs.SuccessIcon(), text.Pluralize(len(files), "asset"))
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runReleaseDownload(cmd *cobra.Command, args []string) error {
|
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
|
|
|
|
dir, _ := cmd.Flags().GetString("dir")
|
|
|
|
|
pattern, _ := cmd.Flags().GetString("pattern")
|
|
|
|
|
tag := args[0]
|
|
|
|
|
|
|
|
|
|
owner, name, err := parseRepo(repo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg, err := config.Load()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ios.StartSpinner("Fetching release...")
|
|
|
|
|
release, err := getReleaseByTagOrLatest(client, owner, name, tag)
|
|
|
|
|
if err != nil {
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
attachments, err := listReleaseAttachments(client, owner, name, release.ID)
|
|
|
|
|
ios.StopSpinner()
|
|
|
|
|
if err != nil {
|
2026-01-05 12:57:37 +01:00
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if len(attachments) == 0 {
|
|
|
|
|
fmt.Fprintf(ios.Out, "No assets found for release %s\n", release.TagName)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Filter by pattern if provided
|
|
|
|
|
var toDownload []*gitea.Attachment
|
|
|
|
|
for _, a := range attachments {
|
|
|
|
|
if pattern != "" {
|
|
|
|
|
matched, matchErr := path.Match(pattern, a.Name)
|
|
|
|
|
if matchErr != nil {
|
|
|
|
|
return fmt.Errorf("invalid glob pattern %q: %w", pattern, matchErr)
|
|
|
|
|
}
|
|
|
|
|
if !matched {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
toDownload = append(toDownload, a)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(toDownload) == 0 {
|
|
|
|
|
fmt.Fprintf(ios.Out, "No assets matching pattern %q in release %s\n", pattern, release.TagName)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ensure download directory exists
|
|
|
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
|
|
|
return fmt.Errorf("failed to create directory %s: %w", dir, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, a := range toDownload {
|
|
|
|
|
destPath := filepath.Join(dir, a.Name)
|
|
|
|
|
f, createErr := os.Create(destPath)
|
|
|
|
|
if createErr != nil {
|
|
|
|
|
return fmt.Errorf("failed to create file %s: %w", destPath, createErr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dlErr := client.DownloadFile(a.DownloadURL, f)
|
|
|
|
|
closeErr := f.Close()
|
|
|
|
|
if dlErr != nil {
|
|
|
|
|
return fmt.Errorf("failed to download %s: %w", a.Name, dlErr)
|
|
|
|
|
}
|
|
|
|
|
if closeErr != nil {
|
|
|
|
|
return fmt.Errorf("failed to close %s: %w", destPath, closeErr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(ios.Out, "Downloaded %s (%d bytes)\n", a.Name, a.Size)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cs := ios.ColorScheme()
|
|
|
|
|
fmt.Fprintf(ios.Out, "\n%s %s downloaded to %s\n", cs.SuccessIcon(), text.Pluralize(len(toDownload), "asset"), dir)
|
2026-01-05 12:57:37 +01:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runReleaseDelete(cmd *cobra.Command, args []string) error {
|
|
|
|
|
repo, _ := cmd.Flags().GetString("repo")
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
yes, _ := cmd.Flags().GetBool("yes")
|
2026-01-05 12:57:37 +01:00
|
|
|
tag := args[0]
|
|
|
|
|
|
|
|
|
|
owner, name, err := parseRepo(repo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg, err := config.Load()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-05 12:47:28 +01:00
|
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost())
|
2026-01-05 12:57:37 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StartSpinner("Fetching release...")
|
2026-01-05 12:57:37 +01:00
|
|
|
release, err := getReleaseByTagOrLatest(client, owner, name, tag)
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2026-01-05 12:57:37 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
if !yes {
|
|
|
|
|
confirmed, err := ios.ConfirmAction(fmt.Sprintf("Delete release %s?", release.TagName))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if !confirmed {
|
|
|
|
|
fmt.Fprintln(ios.ErrOut, "Aborted")
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ios.StartSpinner("Deleting release...")
|
2026-01-05 12:57:37 +01:00
|
|
|
if _, err := client.DeleteRelease(owner, name, release.ID); err != nil {
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2026-01-05 12:57:37 +01:00
|
|
|
return fmt.Errorf("failed to delete release: %w", err)
|
|
|
|
|
}
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
ios.StopSpinner()
|
2026-01-05 12:57:37 +01:00
|
|
|
|
feat: v0.3.0d — add PR checks, iostreams, aliases, and broad enhancements
Add PR checks command, iostreams/text packages for colored table output,
top-level run/workflow aliases matching gh CLI structure. Enhance actions,
issues, PRs, releases, repos, labels, milestones, and wiki commands with
improved flags, JSON output, and error handling.
2026-03-23 11:42:44 -06:00
|
|
|
cs := ios.ColorScheme()
|
|
|
|
|
fmt.Fprintf(ios.Out, "%s Release %s deleted\n", cs.SuccessIcon(), release.TagName)
|
2026-01-05 12:57:37 +01:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getReleaseByTagOrLatest(client *api.Client, owner, name, tag string) (*gitea.Release, error) {
|
|
|
|
|
if strings.EqualFold(tag, "latest") {
|
|
|
|
|
release, _, err := client.GetLatestRelease(owner, name)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to get latest release: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return release, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
release, _, err := client.GetReleaseByTag(owner, name, tag)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to get release: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return release, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func uploadReleaseAssets(client *api.Client, owner, name string, releaseID int64, files []string, clobber bool) error {
|
|
|
|
|
existing := map[string]int64{}
|
|
|
|
|
if clobber {
|
|
|
|
|
attachments, err := listReleaseAttachments(client, owner, name, releaseID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
for _, attachment := range attachments {
|
|
|
|
|
existing[attachment.Name] = attachment.ID
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, file := range files {
|
|
|
|
|
filename := filepath.Base(file)
|
|
|
|
|
if clobber {
|
|
|
|
|
if attachmentID, ok := existing[filename]; ok {
|
|
|
|
|
if _, err := client.DeleteReleaseAttachment(owner, name, releaseID, attachmentID); err != nil {
|
|
|
|
|
return fmt.Errorf("failed to delete existing asset %s: %w", filename, err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handle, err := os.Open(file)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to open %s: %w", file, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, _, err = client.CreateReleaseAttachment(owner, name, releaseID, handle, filename)
|
|
|
|
|
closeErr := handle.Close()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("failed to upload %s: %w", file, err)
|
|
|
|
|
}
|
|
|
|
|
if closeErr != nil {
|
|
|
|
|
return fmt.Errorf("failed to close %s: %w", file, closeErr)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func listReleaseAttachments(client *api.Client, owner, name string, releaseID int64) ([]*gitea.Attachment, error) {
|
|
|
|
|
var all []*gitea.Attachment
|
|
|
|
|
for page := 1; ; page++ {
|
|
|
|
|
attachments, _, err := client.ListReleaseAttachments(owner, name, releaseID, gitea.ListReleaseAttachmentsOptions{
|
|
|
|
|
ListOptions: gitea.ListOptions{Page: page, PageSize: 50},
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to list release assets: %w", err)
|
|
|
|
|
}
|
|
|
|
|
if len(attachments) == 0 {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
all = append(all, attachments...)
|
|
|
|
|
}
|
|
|
|
|
return all, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func releaseType(release *gitea.Release) string {
|
|
|
|
|
if release.IsDraft {
|
|
|
|
|
return "draft"
|
|
|
|
|
}
|
|
|
|
|
if release.IsPrerelease {
|
|
|
|
|
return "prerelease"
|
|
|
|
|
}
|
|
|
|
|
return "release"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func releaseTimestamp(release *gitea.Release) time.Time {
|
|
|
|
|
if !release.PublishedAt.IsZero() {
|
|
|
|
|
return release.PublishedAt
|
|
|
|
|
}
|
|
|
|
|
return release.CreatedAt
|
|
|
|
|
}
|