### Install go-jira via Go Source: https://context7.com/go-jira/jira/llms.txt Installs the jira binary using the Go toolchain. ```bash # Install via Go go get github.com/go-jira/jira/cmd/jira ``` -------------------------------- ### Install go-jira CLI Source: https://github.com/go-jira/jira/blob/master/README.md Build and install the go-jira command-line client from the official repository. Ensure GO111MODULE is set to 'on' before running. ```go go get github.com/go-jira/jira/cmd/jira ``` -------------------------------- ### Dynamic Configuration Script Example Source: https://github.com/go-jira/jira/blob/master/README.md An example of an executable configuration script that sets the Jira endpoint, preferred editor, and applies a 'table' template for 'list' operations. It also conditionally sets assignee and watchers for 'create' operations. ```sh #!/bin/sh echo "endpoint: https://jira.mycompany.com" echo "editor: emacs -nw" case $JIRA_OPERATION in list) echo "template: table";; esac ``` ```sh #!/bin/sh echo "project: GOJIRA" case $JIRA_OPERATION in create) echo "assignee: $USER" echo "watchers: mothra" ;; esac ``` -------------------------------- ### API Token Authentication Header Examples Source: https://github.com/go-jira/jira/blob/master/README.md Examples of Authorization headers for API token authentication, showing both Basic and Bearer schemes. ```text Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQK ``` ```text Authorization: Bearer MY_TOKEN ``` -------------------------------- ### Setup Jira Service for Testing Source: https://github.com/go-jira/jira/blob/master/_t/README.md Script to set up the Jira service required for running tests. This needs to be run before executing other tests and may require daily execution due to a temporary license. ```bash ./000setup.t ``` -------------------------------- ### Run Custom Command with Different Inputs Source: https://github.com/go-jira/jira/blob/master/README.md These examples demonstrate various ways to invoke the 'custom-test' command, highlighting error conditions for missing required arguments/options and successful executions with different argument and option values. It shows how repeated arguments are handled and how to override default option values. ```bash $ jira custom-test ERROR Invalid Usage: required flag --day not provided ``` ```bash $ jira custom-test --day Sunday ERROR Invalid Usage: enum value must be one of Monday,Tuesday,Wednesday,Thursday,Friday, got 'Sunday' ``` ```bash $ jira custom-test --day Tuesday ERROR Invalid Usage: required argument 'ARG' not provided ``` ```bash $ jira custom-test --day Tuesday arg1 COMMAND arg1 --abc default --day Tuesday ``` ```bash $ jira custom-test --day Tuesday arg1 more1 more2 more3 COMMAND arg1 --abc default --day Tuesday more1 more2 more3 ``` ```bash $ jira custom-test --day Tuesday arg1 more1 more2 more3 --abc non-default COMMAND arg1 --abc non-default --day Tuesday more1 more2 more3 ``` ```bash $ jira custom-test --day Tuesday arg1 more1 more2 more3 -a short-non-default COMMAND arg1 --abc short-non-default --day Tuesday more1 more2 more3 ``` -------------------------------- ### Configure gopass Password Source Source: https://github.com/go-jira/jira/blob/master/README.md Add this configuration to `$HOME/.jira.d/config.yml` to use `gopass` for password management. This requires a working `gopass` installation. ```yaml password-source: gopass password-name: jira.example.com/myuser ``` -------------------------------- ### Execute Custom Jira Commands Source: https://context7.com/go-jira/jira/llms.txt Execute custom Jira commands defined in the configuration. These examples demonstrate calling the 'mine', 'bug', and 'sprint-report' commands with various options and arguments. ```bash jira mine jira bug --priority Critical --component "Payment Service" "Checkout crashes on empty cart" jira sprint-report --count 5 ``` -------------------------------- ### AddIssueWorklog Source: https://context7.com/go-jira/jira/llms.txt Posts a worklog entry, including time spent, an optional comment, and the start time, to a specific issue. ```APIDOC ## `AddIssueWorklog` — Log time spent on an issue Posts a worklog entry (time spent + optional comment + start time) to an issue. ### Parameters - `httpClient` (*http.Client) - The HTTP client to use for the request. - `endpoint` (string) - The Jira API endpoint URL. - `issueKey` (string) - The key of the issue to log work against (e.g., "PROJ-789"). - `worklog` (*jiradata.Worklog) - A `Worklog` object containing details like `TimeSpent`, `Comment`, and `Started`. ### Request Example ```go import "github.com/go-jira/jira/jiradata" worklog := &jiradata.Worklog{ TimeSpent: "2h 30m", Comment: "Investigated null pointer and identified root cause", Started: "2024-03-15T09:00:00.000+0000", } posted, err := jira.AddIssueWorklog(httpClient, endpoint, "PROJ-789", worklog) if err != nil { log.Fatalf("AddWorklog: %v", err) } fmt.Printf("Logged %s by %s\n", posted.TimeSpent, posted.Author.DisplayName) // Output: Logged 2h 30m by Jane Smith ``` ### Response - `*jiradata.Worklog` - The posted worklog details upon success. ``` -------------------------------- ### Access Jira Environment Variables in Custom Command Source: https://github.com/go-jira/jira/blob/master/README.md This example shows how a custom command can directly access environment variables set by Jira, such as `JIRA_PROJECT`. The script simply echoes the value of the `JIRA_PROJECT` environment variable. ```yaml custom-commands: - name: print-project help: print the name of the configured project script: "echo $JIRA_PROJECT" ``` -------------------------------- ### Log Work on Jira Issue Source: https://context7.com/go-jira/jira/llms.txt Posts a worklog entry to a Jira issue, including time spent, an optional comment, and the start time of the work. Requires a populated jiradata.Worklog struct. ```go import "github.com/go-jira/jira/jiradata" worklog := &jiradata.Worklog{ TimeSpent: "2h 30m", Comment: "Investigated null pointer and identified root cause", Started: "2024-03-15T09:00:00.000+0000", } posted, err := jira.AddIssueWorklog(httpClient, endpoint, "PROJ-789", worklog) if err != nil { log.Fatalf("AddWorklog: %v", err) } fmt.Printf("Logged %s by %s\n", posted.TimeSpent, posted.Author.DisplayName) // Output: Logged 2h 30m by Jane Smith ``` -------------------------------- ### Initialize pass Tool Source: https://github.com/go-jira/jira/blob/master/README.md Initialize the `pass` tool with your GPG key. Replace "Go Jira " with your actual GPG key details. ```bash pass init "Go Jira " ``` -------------------------------- ### Create and List Project Components Source: https://context7.com/go-jira/jira/llms.txt Manages project components. `CreateComponent` adds a new component, while `GetProjectComponents` lists existing ones. Requires the `jiradata` package. ```go import "github.com/go-jira/jira/jiradata" // Create a component comp := &jiradata.Component{ Name: "Payment Service", Description: "Handles all payment processing logic", Project: "PROJ", LeadUserName: "jsmith", } created, err := jira.CreateComponent(httpClient, endpoint, comp) if err != nil { log.Fatalf("CreateComponent: %v", err) } fmt.Printf("Created component %d: %s\n", created.ID, created.Name) ``` ```go // List project components components, err := jira.GetProjectComponents(httpClient, endpoint, "PROJ") if err != nil { log.Fatal(err) } for _, c := range *components { fmt.Printf(" %s (id=%d)\n", c.Name, c.ID) } ``` -------------------------------- ### Build and Run Integration Tests Source: https://github.com/go-jira/jira/blob/master/_t/README.md Commands to build the local 'jira' binary and run integration tests using the 'prove' command. ```bash # this creates a local "jira" binary make # this runs the integration tests in the "_t" directory prove ``` -------------------------------- ### Configure go-jira with API Token Authentication Source: https://github.com/go-jira/jira/blob/master/README.md Sets up go-jira to use an API token for authentication with Atlassian Cloud. Requires setting subdomain and email, creating a config file, and then running 'jira session' to add the token to the keyring. ```bash export SUBDOMAIN="https://.atlassian.net" export EMAIL="" mkdir -p ~/.jira.d printf "endpoint: $SUBDOMAIN\nuser: $EMAIL\npassword-source: keyring" > ~/.jira.d/config.yml ``` -------------------------------- ### Jira CLI Raw API Request Source: https://context7.com/go-jira/jira/llms.txt Make direct REST API requests to Jira. Supports GET, POST, PUT, and DELETE methods with optional JSON payloads. ```bash jira req /rest/api/2/project/PROJ ``` ```bash jira req --method POST /rest/api/2/issue '{"fields":{"project":{"key":"PROJ"},"summary":"test","issuetype":{"name":"Task"}}}' ``` -------------------------------- ### Run Individual Test with Options Source: https://github.com/go-jira/jira/blob/master/_t/README.md How to execute a specific test file directly. Use the -v option for verbose output and -a to abort on the first failure. ```bash ./100basic.t ``` -------------------------------- ### Configure Jira Endpoint Source: https://github.com/go-jira/jira/blob/master/README.md Set up the Jira endpoint by creating a .jira.d/config.yml file in your home directory. This file specifies the base URL for your Jira instance. ```yaml endpoint: https://jira.mycompany.com ``` -------------------------------- ### Configure Atlassian Cloud Authentication Source: https://context7.com/go-jira/jira/llms.txt Sets up the configuration file for Atlassian Cloud using API token authentication. Prompts for the API token and stores it in the OS keyring. ```bash # Atlassian Cloud (API token auth) mkdir -p ~/.jira.d cat > ~/.jira.d/config.yml < ~/.jira.d/config.yml < ~/.jira.d/config.yml <= 5 ORDER BY rank`, MaxResults: 200, QueryFields: "summary,status,assignee,customfield_10016", } results, err = jira.Search(httpClient, endpoint, rawOpts, jira.WithAutoPagination()) ``` -------------------------------- ### Create Jira API Client with NewJira Source: https://context7.com/go-jira/jira/llms.txt Constructs a *Jira struct to interact with the Jira API. This client can be used for all API methods. ```go package main import ( "fmt" "log" jira "github.com/go-jira/jira" ) func main() { // NewJira creates a client using the oreo HTTP client with cookie jar support client := jira.NewJira("https://mycompany.atlassian.net") // All API methods available on the struct or as package-level functions issue, err := client.GetIssue("PROJ-123", nil) if err != nil { log.Fatal(err) } fmt.Printf("Summary: %v\n", issue.Fields["summary"]) // Output: Summary: Fix login page redirect } ``` -------------------------------- ### List All Jira Fields Source: https://context7.com/go-jira/jira/llms.txt Retrieves a list of all system and custom fields available on the Jira instance. Useful for discovering custom field IDs. ```go fields, err := jira.GetFields(httpClient, endpoint) if err != nil { log.Fatal(err) } for _, f := range fields { if f.Custom { fmt.Printf("Custom field: id=%s name=%s type=%s\n", f.ID, f.Name, f.Schema.Type) } } // Output: // Custom field: id=customfield_10016 name=Story Points type=number // Custom field: id=customfield_10110 name=Epic Link type=any ``` -------------------------------- ### Configure Keyring Password Source Source: https://github.com/go-jira/jira/blob/master/README.md Enable 'password-source: keyring' in your config.yml to automatically store your credentials in your OS's native keyring after a 'jira login' command. ```yaml password-source: keyring ``` -------------------------------- ### Component Management Source: https://context7.com/go-jira/jira/llms.txt Functions for creating new components in a project and listing existing components. ```APIDOC ## CreateComponent / GetProjectComponents — Project component management Creates a new component in a project or lists existing components. ### Create a component ```go comp := &jiradata.Component{ Name: "Payment Service", Description: "Handles all payment processing logic", Project: "PROJ", LeadUserName: "jsmith", } created, err := jira.CreateComponent(httpClient, endpoint, comp) if err != nil { log.Fatalf("CreateComponent: %v", err) } fmt.Printf("Created component %d: %s\n", created.ID, created.Name) ``` ### List project components ```go components, err := jira.GetProjectComponents(httpClient, endpoint, "PROJ") if err != nil { log.Fatal(err) } for _, c := range *components { fmt.Printf(" %s (id=%d)\n", c.Name, c.ID) } ``` ``` -------------------------------- ### Generate GPG Key Source: https://github.com/go-jira/jira/blob/master/README.md Use this command to generate a new GPG key if you don't have one already. This is a prerequisite for using `pass` or `gopass`. ```bash gpg --gen-key ``` -------------------------------- ### Configure gpg-agent for Passphrase Caching Source: https://github.com/go-jira/jira/blob/master/README.md Add this configuration to your `$HOME/.bashrc` to set up `gpg-agent` for automatic passphrase caching. This avoids repeated prompts for GPG decryption. ```bash if [ -f $HOME/.gpg-agent-info ]; then . $HOME/.gpg-agent-info export GPG_AGENT_INFO fi if [ ! -f $HOME/.gpg-agent.conf ]; then cat <$HOME/.gpg-agent.conf default-cache-ttl 604800 max-cache-ttl 604800 default-cache-ttl-ssh 604800 max-cache-ttl-ssh 604800 EOM fi if [ -n "${GPG_AGENT_INFO}" ]; then nc -U "${GPG_AGENT_INFO%%:*}" >/dev/null = 5 ORDER BY rank`, MaxResults: 200, QueryFields: "summary,status,assignee,customfield_10016", } results, err = jira.Search(httpClient, endpoint, rawOpts, jira.WithAutoPagination()) ``` ``` -------------------------------- ### Fetch Jira Issue Worklogs and Comments Source: https://context7.com/go-jira/jira/llms.txt Fetches all worklogs or comments for a given Jira issue. The function handles pagination automatically, retrieving up to 100 items per page. ```go // Fetch all worklogs worklogs, err := jira.GetIssueWorklog(httpClient, endpoint, "PROJ-789") if err != nil { log.Fatal(err) } total := 0 for _, w := range *worklogs { fmt.Printf(" %s spent %s: %s\n", w.Author.DisplayName, w.TimeSpent, w.Comment) total++ } fmt.Printf("Total worklog entries: %d\n", total) // Fetch all comments comments, err := jira.GetIssueComment(httpClient, endpoint, "PROJ-789") if err != nil { log.Fatal(err) } for _, c := range *comments { fmt.Printf(" [%s] %s: %.80s\n", c.Created, c.Author.DisplayName, c.Body) } ``` -------------------------------- ### Jira CLI - Worklog Source: https://context7.com/go-jira/jira/llms.txt Adds worklog entries to issues. Specify time spent and an optional comment. Use `--noedit` to bypass the editor. ```bash # Worklog jira worklog add PROJ-789 --time-spent "3h" --comment "Fixed the bug" --noedit ``` -------------------------------- ### Debug Template Data for 'list' Operation Source: https://github.com/go-jira/jira/blob/master/README.md Use the '-t debug' flag with the 'list' command to print available data in JSON format for template customization. ```bash jira list -t debug ``` -------------------------------- ### Fetch Jira Issue with Options Source: https://context7.com/go-jira/jira/llms.txt Retrieves a Jira issue using specific fields, expand options, and update history. Handles potential errors by implementing jiradata.ErrorCollection. ```go import ( jira "github.com/go-jira/jira" ) // Fetch with field and expand options opts := &jira.IssueOptions{ Fields: []string{"summary", "status", "assignee", "description"}, Expand: []string{"renderedFields"}, UpdateHistory: true, } issue, err := jira.GetIssue(httpClient, "https://mycompany.atlassian.net", "PROJ-456", opts) if err != nil { // err implements jiradata.ErrorCollection with Status and ErrorMessages log.Fatalf("GetIssue failed: %v", err) } fmt.Println(issue.Key, issue.Fields["summary"]) ``` -------------------------------- ### TransitionIssue / GetIssueTransitions Source: https://context7.com/go-jira/jira/llms.txt Fetches available workflow transitions for an issue and allows transitioning it to a new state. Transition IDs can be resolved by name within the metadata. ```APIDOC ## `TransitionIssue` / `GetIssueTransitions` — Workflow state transitions Fetches available transitions and moves an issue to a new state. Transition IDs are resolved by name within the metadata. ```go // List available transitions meta, err := jira.GetIssueTransitions(httpClient, endpoint, "PROJ-789") if err != nil { log.Fatal(err) } for _, t := range meta.Transitions { fmt.Printf(" [%s] %s\n", t.ID, t.Name) } // Output: // [11] To Do // [21] In Progress // [31] Done // Transition to Done with a resolution issueUpdate := &jiradata.IssueUpdate{ Transition: &jiradata.TransitionPayload{ID: "31"}, Fields: map[string]interface{}{ "resolution": map[string]string{"name": "Fixed"}, }, Update: map[string]interface{}{ "comment": []map[string]interface{}{ {"add": map[string]string{"body": "Resolved in PR #142"}}, }, }, } err = jira.TransitionIssue(httpClient, endpoint, "PROJ-789", issueUpdate) if err != nil { log.Fatalf("TransitionIssue: %v", err) } // HTTP 204 on success ``` ``` -------------------------------- ### Transition Jira Issue Workflow State Source: https://context7.com/go-jira/jira/llms.txt Use `GetIssueTransitions` to list available workflow transitions for an issue and `TransitionIssue` to move it to a new state. Transition IDs can be resolved by name. A resolution and comment can be included in the transition payload. ```go // List available transitions meta, err := jira.GetIssueTransitions(httpClient, endpoint, "PROJ-789") if err != nil { log.Fatal(err) } for _, t := range meta.Transitions { fmt.Printf(" [%s] %s\n", t.ID, t.Name) } // Output: // [11] To Do // [21] In Progress // [31] Done // Transition to Done with a resolution issueUpdate := &jiradata.IssueUpdate{ Transition: &jiradata.TransitionPayload{ID: "31"}, Fields: map[string]interface{}{ "resolution": map[string]string{"name": "Fixed"}, }, Update: map[string]interface{}{ "comment": []map[string]interface{}{{"add": map[string]string{"body": "Resolved in PR #142"}}}, }, } err = jira.TransitionIssue(httpClient, endpoint, "PROJ-789", issueUpdate) if err != nil { log.Fatalf("TransitionIssue: %v", err) } // HTTP 204 on success ``` -------------------------------- ### Define Custom Commands in Configuration Source: https://github.com/go-jira/jira/blob/master/README.md Specify custom commands by listing their names in the 'custom-commands' section of your .jira.d/config.yml file. These commands are typically shell scripts. ```yaml custom-commands: - command1 - command2 ``` -------------------------------- ### Configure User and Login for API Tokens Source: https://github.com/go-jira/jira/blob/master/README.md When using API tokens, specify both 'user' for Jira API calls and 'login' for authentication purposes in your config.yml. This is useful when your login email differs from your Jira username. ```yaml user: person login: person@example.com ``` -------------------------------- ### Jira CLI Commands Source: https://context7.com/go-jira/jira/llms.txt Command-line interface for various Jira operations including viewing, listing, creating, editing, and transitioning issues. ```APIDOC ## `jira` CLI — view, list, create, edit, transition commands The binary provides subcommands for every operation. All commands load config from `.jira.d/config.yml` hierarchy and support `--template`, `--gjq` (GJSON filter), and `--browse` flags. ### View an issue ```bash # View a single issue (jira PROJ-123 also works as shorthand) jira view PROJ-789 jira view PROJ-789 --template json jira view PROJ-789 --gjq "fields.status.name" # Output: In Progress ``` ### List issues ```bash # List issues with JQL jira list --query "project = PROJ AND sprint in openSprints() AND assignee = currentUser()" jira list --project PROJ --status "In Progress" --assignee jane@example.com jira list --project PROJ --limit 20 --sort "priority asc" ``` ### Create an issue ```bash # Create an issue (opens editor with YAML template) jira create --project PROJ --issuetype Bug --summary "Login fails on Safari" # Skip editor with --noedit and --override jira create --project PROJ -i Bug -s "Login fails" --noedit \ -o priority=High -o assignee=jane@example.com ``` ### Edit an issue ```bash jira edit PROJ-789 jira edit PROJ-789 --override priority=Critical --noedit ``` ### Transition an issue ```bash jira transition "In Progress" PROJ-789 jira transition Done PROJ-789 --comment "Deployed to prod in v2.4.0" # Shorthand commands jira close PROJ-789 jira resolve PROJ-789 jira reopen PROJ-789 ``` ### Add a comment ```bash jira comment PROJ-789 --comment "Confirmed fix works in staging" jira comment PROJ-789 # opens editor ``` ### Assign / unassign ```bash jira assign PROJ-789 jane@example.com jira unassign PROJ-789 ``` ### Worklog ```bash jira worklog add PROJ-789 --time-spent "3h" --comment "Fixed the bug" --noedit ``` ``` -------------------------------- ### Jira CLI - Add Comment, Assign, and Unassign Source: https://context7.com/go-jira/jira/llms.txt Commands for adding comments to issues and managing issue assignments. ```bash # Add a comment jira comment PROJ-789 --comment "Confirmed fix works in staging" jira comment PROJ-789 # opens editor ``` ```bash # Assign / unassign jira assign PROJ-789 jane@example.com jira unassign PROJ-789 ``` -------------------------------- ### Create Jira Issue Source: https://context7.com/go-jira/jira/llms.txt Use `CreateIssue` to create a new Jira issue. The `IssueUpdateProvider` interface allows decoupling the data source from the HTTP call. Ensure `httpClient` and `issueUpdate` are properly initialized. ```go import ( "github.com/go-jira/jira/jiradata" jira "github.com/go-jira/jira" ) issueUpdate := &jiradata.IssueUpdate{ Fields: map[string]interface{}{ "project": map[string]string{"key": "PROJ"}, "issuetype": map[string]string{"name": "Bug"}, "summary": "Null pointer exception in payment service", "priority": map[string]string{"name": "High"}, "description": "Steps to reproduce:\n1. Go to /checkout\n2. Submit with empty cart", }, } resp, err := jira.CreateIssue(httpClient, "https://mycompany.atlassian.net", issueUpdate) if err != nil { log.Fatalf("CreateIssue: %v", err) } fmt.Printf("Created %s: %s/browse/%s\n", resp.Key, endpoint, resp.Key) // Output: Created PROJ-789: https://mycompany.atlassian.net/browse/PROJ-789 ``` -------------------------------- ### Assign Jira Issue Source: https://context7.com/go-jira/jira/llms.txt Assigns an issue to a user. For server deployments, use username; for cloud, use accountId. Pass an empty string to unassign. ```go // Server deployment: assign by username err := jira.IssueAssign(httpClient, endpoint, "PROJ-789", "jsmith") if err != nil { log.Fatal(err) } // Cloud deployment: assign by accountId (GDPR-compliant) err = jira.IssueAssignAccountID(httpClient, endpoint, "PROJ-789", "5b10ac8d82e05b22cc7d4ef5") if err != nil { log.Fatal(err) } // Unassign err = jira.IssueAssign(httpClient, endpoint, "PROJ-789", "") if err != nil { log.Fatal(err) } ``` -------------------------------- ### Define Custom Command to Print Environment Variables Source: https://github.com/go-jira/jira/blob/master/README.md This YAML defines an 'env' command that prints all environment variables prefixed with 'JIRA'. This is useful for debugging and understanding the environment variables available to custom commands. ```yaml custom-commands: - name: env help: print the JIRA environment variables available to custom commands script: | env | grep JIRA ``` -------------------------------- ### Define Custom Jira Commands in YAML Source: https://context7.com/go-jira/jira/llms.txt Define custom commands for Jira workflows using YAML configuration. These commands can be extended with options and arguments, and their scripts can leverage Jira's CLI and Go templating. ```yaml custom-commands: - name: mine help: List issues assigned to me in the current sprint script: | {{jira}} list --template table \ --query "sprint in openSprints() AND assignee = currentUser() AND resolution = unresolved ORDER BY priority asc" - name: bug help: Create a bug with mandatory priority options: - name: priority short: P type: ENUM enum: [Blocker, Critical, Major, Minor] required: true - name: component short: c args: - name: SUMMARY required: true script: | {{jira}} create --project $JIRA_PROJECT -i Bug -s "{{args.SUMMARY}}" --noedit \ -o priority={{options.priority}} \ {{if options.component}}-o component={{options.component}}{{end}} - name: sprint-report help: Show sprint velocity for the last N sprints options: - name: count short: n default: "3" script: | {{jira}} list --template table \ --query "project = $JIRA_PROJECT AND sprint in closedSprints() ORDER BY updated desc" \ --limit {{options.count}} ``` -------------------------------- ### Search, Add, and Remove Issues from Epics Source: https://context7.com/go-jira/jira/llms.txt Use these functions to manage issues within epics. Ensure the `httpClient` and `endpoint` are properly configured. `EpicRemoveIssues` moves issues to the backlog. ```go import "github.com/go-jira/jira/jiradata" // Search issues in an epic searchOpts := &jira.SearchOptions{ Status: "In Progress", QueryFields: "summary,assignee,status", } results, err := jira.EpicSearch(httpClient, endpoint, "PROJ-50", searchOpts) if err != nil { log.Fatal(err) } fmt.Printf("Epic PROJ-50 has %d in-progress issues\n", len(results.Issues)) ``` ```go // Add issues to an epic epicIssues := &jiradata.EpicIssues{ Issues: []string{"PROJ-789", "PROJ-790", "PROJ-791"}, } err = jira.EpicAddIssues(httpClient, endpoint, "PROJ-50", epicIssues) if err != nil { log.Fatalf("EpicAddIssues: %v", err) } ``` ```go // Remove issues from their epic (moves to backlog) err = jira.EpicRemoveIssues(httpClient, endpoint, epicIssues) if err != nil { log.Fatalf("EpicRemoveIssues: %v", err) } ``` -------------------------------- ### IssueAttachFile Source: https://context7.com/go-jira/jira/llms.txt Uploads a file as a multipart form POST to attach it to a Jira issue. It automatically sets the required `X-Atlassian-Token: no-check` header. ```APIDOC ## `IssueAttachFile` — Attach a file to an issue Uploads a file as a multipart form POST, setting the required `X-Atlassian-Token: no-check` header automatically. ### Parameters - `httpClient` (*http.Client) - The HTTP client to use for the request. - `endpoint` (string) - The Jira API endpoint URL. - `issueKey` (string) - The key of the issue to attach the file to (e.g., "PROJ-789"). - `filename` (string) - The name of the file to be attached. - `file` (*os.File) - The file to upload. ### Request Example ```go import "os" f, err := os.Open("/tmp/heapdump.hprof") if err != nil { log.Fatal(err) } defer f.Close() attachments, err := jira.IssueAttachFile(httpClient, endpoint, "PROJ-789", "heapdump.hprof", f) if err != nil { log.Fatalf("IssueAttachFile: %v", err) } for _, a := range *attachments { fmt.Printf("Attached: id=%d filename=%s url=%s\n", a.ID, a.Filename, a.Content) } ``` ### Response - `*[]jiradata.Attachment` - A slice of attachment information upon success. ``` -------------------------------- ### Use stdin for Password Input Source: https://github.com/go-jira/jira/blob/master/README.md When `password-source` is set to `stdin`, the `jira login` command reads the password from standard input until EOF. This is useful for programmatic password generation. ```bash ./password-generator | jira login --endpoint=https://my.jira.endpoint.com --user=USERNAME ```