Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
3061f88
fix: preserve raw JQL ordering (#1)
hackerh3 Mar 26, 2026
e6dfa74
ci: add safe manual build trigger
hackerh3 Mar 26, 2026
d1a9bd2
feat: add Deviniti Issue Template support for issue creation
hackerh3 Apr 9, 2026
e58dbc4
fix: add plain output for project list
hackerh3 Apr 15, 2026
4f93130
fix(lint): suppress gocyclo for getRequestData
hackerh3 Apr 15, 2026
2cbef84
Merge pull request #2 from hackerh3/ci/fork-safe-build-trigger
hackerh3 Apr 17, 2026
8b17182
fix(jira): detect broken workflow and suggest move-project workaround
hackerh3 Apr 21, 2026
70713a3
feat(jira): add JSP session client with cookie jar
hackerh3 Apr 21, 2026
53dd911
feat(jira): add move-project API via JSP form wizard
hackerh3 Apr 21, 2026
e4b8e97
feat(jira): add move-project CLI command
hackerh3 Apr 21, 2026
e28a8b8
fix(jira): confirm step needs confirm=true + smart key extraction
hackerh3 Apr 21, 2026
0ec114d
fix: resolve golangci-lint failures in move-project code
hackerh3 Apr 21, 2026
89e9b25
Merge pull request #3 from hackerh3/hhaecker/jira-cli-move-project
hackerh3 Apr 21, 2026
71f6b5a
feat(api): add GetIssueComment and UpdateIssueComment
hackerh3 May 11, 2026
e27710d
feat(cmd): add comment edit subcommand
hackerh3 May 11, 2026
81ea20c
style(cmd): fix gofmt alignment in comment edit
hackerh3 May 11, 2026
5735518
Merge pull request #8 from hackerh3/hhaecker/jira-cli-move-project
hackerh3 May 11, 2026
6136394
ci: add semantic-release with conventionalcommits and goreleaser pipe…
hackerh3 May 11, 2026
d84022a
Merge pull request #9 from hackerh3/hhaecker/semantic-release
hackerh3 May 11, 2026
6743d3a
fix(ci): use goreleaser append mode to upload binaries to existing re…
hackerh3 May 11, 2026
a9fd0de
Merge pull request #10 from hackerh3/hhaecker/goreleaser-append
hackerh3 May 11, 2026
2c4f8df
ci: switch to versionless tag format (1.x.0) to avoid upstream collis…
hackerh3 May 12, 2026
a83ae64
docs: update README with fork install instructions, prevent upstream …
hackerh3 May 12, 2026
d267e3a
ci: add daily upstream activity watcher [skip ci]
hackerh3 May 12, 2026
5cf0eca
fix(ci): flatten archive layout and build all platforms
hackerh3 May 12, 2026
b3cc236
chore(release): 1.8.1 [skip ci]
semantic-release-bot May 12, 2026
43374ef
fix(comment): move markdown conversion to command layer, add --raw flag
hackerh3 May 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
on:
workflow_dispatch:
pull_request:
types: [opened, synchronize, reopened]
release:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ name: Publish a Docker image
run-name: Docker image for ${{ github.ref_name }}

on:
workflow_dispatch:
release:
types: [published, prereleased]

Expand Down
65 changes: 65 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Release

on:
push:
branches: [main]

permissions:
contents: write
issues: write
pull-requests: write

jobs:
release:
name: Semantic Release
runs-on: ubuntu-latest
outputs:
new_release_published: ${{ steps.semantic.outputs.new_release_published }}
new_release_version: ${{ steps.semantic.outputs.new_release_version }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22

- name: Semantic Release
id: semantic
uses: cycjimmy/semantic-release-action@v4
with:
extra_plugins: |
@semantic-release/changelog
@semantic-release/git
conventional-changelog-conventionalcommits
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

goreleaser:
name: Build & Upload Binaries
needs: release
if: needs.release.outputs.new_release_published == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ needs.release.outputs.new_release_version }}

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '^1.25.6'

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
version: '~> v2'
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
126 changes: 126 additions & 0 deletions .github/workflows/upstream-watch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: Upstream Watch

on:
schedule:
- cron: '0 7 * * *' # daily at 07:00 UTC
workflow_dispatch: {}

permissions:
contents: read
issues: write

env:
UPSTREAM: ankitpokhrel/jira-cli

jobs:
check:
name: Check upstream activity
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Add upstream remote
run: |
git remote add upstream "https://github.com/${{ env.UPSTREAM }}.git"
git fetch upstream main --tags --quiet

- name: Detect new commits
id: commits
run: |
BASE=$(git merge-base HEAD upstream/main 2>/dev/null || echo "")
UPSTREAM_HEAD=$(git rev-parse upstream/main)

if [ -z "$BASE" ]; then
echo "count=unknown" >> "$GITHUB_OUTPUT"
echo "summary=Could not determine merge-base" >> "$GITHUB_OUTPUT"
elif [ "$BASE" = "$UPSTREAM_HEAD" ]; then
echo "count=0" >> "$GITHUB_OUTPUT"
echo "summary=Up to date with upstream" >> "$GITHUB_OUTPUT"
else
COUNT=$(git rev-list --count "$BASE".."$UPSTREAM_HEAD")
LOG=$(git log --oneline "$BASE".."$UPSTREAM_HEAD" | head -20)
echo "count=$COUNT" >> "$GITHUB_OUTPUT"

# write multi-line log to output
{
echo "log<<LOGEOF"
echo "$LOG"
echo "LOGEOF"
} >> "$GITHUB_OUTPUT"
echo "summary=$COUNT new commit(s) on upstream main" >> "$GITHUB_OUTPUT"
fi

- name: Detect new releases
id: releases
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# get latest upstream release tag
LATEST=$(gh api "repos/${{ env.UPSTREAM }}/releases/latest" --jq '.tag_name' 2>/dev/null || echo "")

if [ -z "$LATEST" ]; then
echo "new=false" >> "$GITHUB_OUTPUT"
exit 0
fi

# check if we have this tag as an ancestor
if git merge-base --is-ancestor "$LATEST" HEAD 2>/dev/null; then
echo "new=false" >> "$GITHUB_OUTPUT"
else
RELEASE_DATE=$(gh api "repos/${{ env.UPSTREAM }}/releases/latest" --jq '.published_at')
echo "new=true" >> "$GITHUB_OUTPUT"
echo "tag=$LATEST" >> "$GITHUB_OUTPUT"
echo "date=$RELEASE_DATE" >> "$GITHUB_OUTPUT"
fi

- name: Create or update tracking issue
if: steps.commits.outputs.count != '0' || steps.releases.outputs.new == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TITLE="upstream: new activity detected"
LABEL="upstream-watch"

# ensure label exists
gh label create "$LABEL" --description "Automated upstream tracking" --color "0E8A16" 2>/dev/null || true

# build issue body
BODY="## Upstream Activity Report

**Checked**: $(date -u '+%Y-%m-%d %H:%M UTC')
**Upstream**: [${{ env.UPSTREAM }}](https://github.com/${{ env.UPSTREAM }})

### Commits
${{ steps.commits.outputs.summary }}
"

if [ "${{ steps.commits.outputs.count }}" != "0" ] && [ "${{ steps.commits.outputs.count }}" != "unknown" ]; then
BODY="$BODY
\`\`\`
${{ steps.commits.outputs.log }}
\`\`\`
"
fi

if [ "${{ steps.releases.outputs.new }}" = "true" ]; then
BODY="$BODY
### New Release
**${{ steps.releases.outputs.tag }}** (published ${{ steps.releases.outputs.date }})
https://github.com/${{ env.UPSTREAM }}/releases/tag/${{ steps.releases.outputs.tag }}
"
fi

BODY="$BODY
---
*Close this issue after syncing. A new one will be created on next detection.*"

# close any existing open issue with the label, then create fresh
EXISTING=$(gh issue list --label "$LABEL" --state open --json number --jq '.[0].number' 2>/dev/null || echo "")
if [ -n "$EXISTING" ]; then
gh issue close "$EXISTING" --comment "Superseded by new check."
fi

gh issue create --title "$TITLE" --body "$BODY" --label "$LABEL"
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
*.out
*.swp
/*.json
!.releaserc.json

.DS_Store
.idea/
Expand All @@ -14,3 +15,5 @@ vendor/
/.gocache

.vscode/
.playwright-mcp/
.sisyphus/
10 changes: 5 additions & 5 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ project_name: jira

release:
prerelease: auto
name_template: "v{{.Version}}"
draft: true
mode: "keep-existing"
name_template: "{{.Version}}"
draft: false
mode: "append"

before:
hooks:
- go mod tidy

builds:
- <<: &build_defaults
binary: bin/jira
binary: jira
main: ./cmd/jira
ldflags:
- -s -w
Expand Down Expand Up @@ -42,7 +42,7 @@ archives:
<<: &archive_defaults
name_template: >-
{{ .ProjectName }}_{{ .Version }}_{{- if eq .Os "darwin" }}macOS{{- else }}{{ .Os }}{{- end }}_{{- if eq .Arch "amd64" }}x86_64{{- else if eq .Arch "386" }}i386{{- else }}{{ .Arch }}{{- end }}{{- if .Arm }}v{{ .Arm }}{{ end -}}
wrap_in_directory: true
wrap_in_directory: false
formats: [tar.gz]
files:
- LICENSE
Expand Down
53 changes: 53 additions & 0 deletions .releaserc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"tagFormat": "${version}",
"branches": ["main"],
"plugins": [
["@semantic-release/commit-analyzer", {
"preset": "conventionalcommits",
"releaseRules": [
{ "breaking": true, "release": "major" },
{ "type": "break", "release": "major" },
{ "type": "feat", "release": "minor" },
{ "type": "fix", "release": "patch" },
{ "type": "perf", "release": "patch" },
{ "type": "revert", "release": "patch" },
{ "type": "deps", "release": "patch" },
{ "type": "refactor", "release": false },
{ "type": "style", "release": false },
{ "type": "docs", "release": false },
{ "type": "build", "release": false },
{ "type": "ci", "release": false },
{ "type": "test", "release": false },
{ "type": "chore", "release": false }
]
}],
["@semantic-release/release-notes-generator", {
"preset": "conventionalcommits",
"presetConfig": {
"types": [
{ "type": "feat", "section": "Features" },
{ "type": "fix", "section": "Bug Fixes" },
{ "type": "perf", "section": "Performance" },
{ "type": "revert", "section": "Reverts" },
{ "type": "deps", "section": "Dependencies" },
{ "type": "break", "section": "Breaking Changes" },
{ "type": "refactor", "section": "Code Refactoring", "hidden": true },
{ "type": "style", "section": "Styles", "hidden": true },
{ "type": "docs", "section": "Documentation", "hidden": true },
{ "type": "build", "section": "Build System", "hidden": true },
{ "type": "ci", "section": "CI", "hidden": true },
{ "type": "test", "section": "Tests", "hidden": true },
{ "type": "chore", "section": "Miscellaneous", "hidden": true }
]
}
}],
["@semantic-release/changelog", {
"changelogFile": "CHANGELOG.md"
}],
"@semantic-release/github",
["@semantic-release/git", {
"assets": ["CHANGELOG.md"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}]
]
}
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
## [1.8.1](https://github.com/hackerh3/jira-cli/compare/1.8.0...1.8.1) (2026-05-12)

### Bug Fixes

* **ci:** flatten archive layout and build all platforms ([5cf0eca](https://github.com/hackerh3/jira-cli/commit/5cf0ecab63fc9b70358ae0f7c99bd4b9d6eac2a2))

# Changelog

All notable changes to the hackerh3/jira-cli fork are documented here.
This fork uses versionless tags (e.g. `1.8.0`) to distinguish from upstream `v1.x.0`.

## [1.8.0](https://github.com/hackerh3/jira-cli/releases/tag/1.8.0) (2026-05-12)

First release under the new versioning scheme. Incorporates all upstream
changes through v1.7.0 plus fork-exclusive features.

### Features

* **jira:** add move-project command for moving issues between projects ([e4b8e97](https://github.com/hackerh3/jira-cli/commit/e4b8e97))
* **jira:** add move-project API via JSP form wizard ([53dd911](https://github.com/hackerh3/jira-cli/commit/53dd911))
* **jira:** add JSP session client with cookie jar ([70713a3](https://github.com/hackerh3/jira-cli/commit/70713a3))
* **api:** add GetIssueComment and UpdateIssueComment ([71f6b5a](https://github.com/hackerh3/jira-cli/commit/71f6b5a))
* **cmd:** add comment edit subcommand ([e27710d](https://github.com/hackerh3/jira-cli/commit/e27710d))
* **jira:** add Deviniti Issue Template support for issue creation ([d1a9bd2](https://github.com/hackerh3/jira-cli/commit/d1a9bd2))

### Bug Fixes

* **jira:** detect broken workflow and suggest move-project workaround ([8b17182](https://github.com/hackerh3/jira-cli/commit/8b17182))
* **jira:** confirm step needs confirm=true + smart key extraction ([e28a8b8](https://github.com/hackerh3/jira-cli/commit/e28a8b8))
* resolve golangci-lint failures in move-project code ([0ec114d](https://github.com/hackerh3/jira-cli/commit/0ec114d))
* add plain output for project list ([e58dbc4](https://github.com/hackerh3/jira-cli/commit/e58dbc4))
* preserve raw JQL ordering ([3061f88](https://github.com/hackerh3/jira-cli/commit/3061f88))

### CI/CD

* semantic-release pipeline with goreleaser cross-compilation
* versionless tag format (`1.x.0`) to avoid upstream collision
30 changes: 16 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<div align="center">
<a href="#">
<img alt="stargazers over time" src="https://stars.medv.io/ankitpokhrel/jira-cli.svg" />
</a>
<h1 align="center">JiraCLI</h1>
<h1 align="center">JiraCLI (hackerh3 fork)</h1>
</div>

> **Fork notice** — This is a maintained fork of [ankitpokhrel/jira-cli](https://github.com/ankitpokhrel/jira-cli).
> It adds move-project, comment editing, Deviniti template support, and broken-workflow detection.
> Releases use versionless tags (`1.8.0`) to avoid collision with upstream (`v1.8.0`).
> Install from **this repo's** [releases page](https://github.com/hackerh3/jira-cli/releases).

<div>
<p align="center">
<a href="https://github.com/ankitpokhrel/jira-cli/actions?query=workflow%3Abuild+branch%3Amaster">
Expand Down Expand Up @@ -69,20 +71,20 @@ nature of the data. Yet, we've attempted to make the experience as similar as po
| **Jira** | <a href="#"><img alt="Jira Cloud" src="https://img.shields.io/badge/Jira Cloud-%E2%9C%93-dark--green?logo=jira&style=flat-square" /></a><a href="#"><img alt="Jira Server" src="https://img.shields.io/badge/Jira Server-%E2%9C%93-dark--green?logo=jira&style=flat-square" /></a> |

## Installation
`jira-cli` is available as a downloadable packaged binary for Linux, macOS, and Windows from the [releases page](https://github.com/ankitpokhrel/jira-cli/releases).
`jira-cli` is available as a downloadable binary for Linux, macOS, and Windows from the [releases page](https://github.com/hackerh3/jira-cli/releases).

> [!WARNING]
> Do **not** install via `brew install jira-cli` or the upstream releases page — those ship the
> upstream binary without fork features. Use the link above or `go install` from this repo.

You can use Docker to quickly try out `jira-cli`.
You can also build from source:

```sh
docker run -it --rm ghcr.io/ankitpokhrel/jira-cli:latest
# Build from this fork
git clone https://github.com/hackerh3/jira-cli.git && cd jira-cli
make deps install
```

Follow the [installation guide](https://github.com/ankitpokhrel/jira-cli/wiki/Installation) for other installation methods like `Homebrew`, `Nix`, etc.

<a href="https://repology.org/project/jira-cli-go/versions">
<img src="https://repology.org/badge/vertical-allrepos/jira-cli-go.svg" alt="Packaging status">
</a>

## Getting started

#### Cloud server
Expand Down Expand Up @@ -807,7 +809,7 @@ Please [open a discussion](https://github.com/ankitpokhrel/jira-cli/discussions/
## Development
1. Clone the repo.
```sh
git clone git@github.com:ankitpokhrel/jira-cli.git
git clone git@github.com:hackerh3/jira-cli.git
```

2. Optional: If you want to run a Jira instance locally, you can use the following make recipe.
Expand Down
Loading
Loading