Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 19 additions & 0 deletions .devcontainer/devcontainer-lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"features": {
"ghcr.io/devcontainers/features/common-utils": {
"version": "2.5.9",
"resolved": "ghcr.io/devcontainers/features/common-utils@sha256:cb0c4d3c276f157eed17935747e364178d75fee17f55c4e129966f64633deb3a",
"integrity": "sha256:cb0c4d3c276f157eed17935747e364178d75fee17f55c4e129966f64633deb3a"
},
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"version": "2.17.0",
"resolved": "ghcr.io/devcontainers/features/docker-in-docker@sha256:25b9f05705ffba7dbe503230ac76081419306f8c8bc88e0ce78c4ecd99a0c78c",
"integrity": "sha256:25b9f05705ffba7dbe503230ac76081419306f8c8bc88e0ce78c4ecd99a0c78c"
},
"ghcr.io/jsburckhardt/devcontainer-features/just:1": {
"version": "1.0.0",
"resolved": "ghcr.io/jsburckhardt/devcontainer-features/just@sha256:5c90013b36669270be21c69e7d8e5b6148b4b0b34fca9e104a599edf0d7c11af",
"integrity": "sha256:5c90013b36669270be21c69e7d8e5b6148b4b0b34fca9e104a599edf0d7c11af"
}
}
}
8 changes: 5 additions & 3 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"image": "mcr.microsoft.com/devcontainers/javascript-node:1-20-bookworm",
"image": "mcr.microsoft.com/devcontainers/base:noble",
"customizations": {
"vscode": {
"settings": {
Expand All @@ -18,13 +18,15 @@
}
},
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
"ghcr.io/devcontainers/features/docker-in-docker:4": {},
"ghcr.io/devcontainers/features/node:2": {
"version": "20"
},
"ghcr.io/jsburckhardt/devcontainer-features/just:1": {},
"ghcr.io/devcontainers/features/common-utils": {
"installOhMyZsh": true,
"configureZshAsDefaultShell": true
}
},
"remoteUser": "node",
"updateContentCommand": "npm install -g @devcontainers/cli"
}
2 changes: 2 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
# copilot-metrics-lgtm is intentionally excluded here: it requires Docker
# (docker-in-docker) which the autogenerated test image does not provide.
# It is exercised in the test-scenarios job instead.
- atlassian-jira-confluence-cli
baseImage:
- debian:latest
- ubuntu:latest
Expand All @@ -46,6 +47,7 @@ jobs:
- copilot-persistence
- gitlab-ci-local
- copilot-metrics-lgtm
- atlassian-jira-confluence-cli
steps:
- uses: actions/checkout@v4

Expand Down
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,44 @@ Persists GitHub Copilot CLI settings and chat history across container rebuilds
- Command history
- Trusted folders

### Atlassian CLI for Jira & Confluence

Installs the [Atlassian CLI](https://developer.atlassian.com/cloud/acli/) (`acli`) for working with Jira and Confluence Cloud from the command line.

**Usage:**

```json
{
"features": {
"ghcr.io/rosstaco/devcontainer-features/atlassian-jira-confluence-cli:1": {
"version": "latest"
}
}
}
```

**Options:**
- `version` - Version of acli to install (default: "latest"). Use "latest" or a specific version like "1.3.21"
- `installPath` - Directory where the acli binary will be installed (default: "/usr/local/bin")
- `configureBrowser` - Install an `xdg-open` shim that prefers `$BROWSER` so `acli auth login` opens on your host (default: `true`)

**Supported Architectures:**
- amd64 (x86_64)
- arm64 (aarch64)

**Getting Started:**

After the container starts, authenticate once and then use the Jira and Confluence commands:

```bash
acli auth login
acli jira project list
```

**Browser Login:**

`acli auth login` opens an OAuth page via `xdg-open`, which doesn't honor `$BROWSER` inside a dev container. With `configureBrowser` enabled (the default), the feature installs a small `xdg-open` shim at `/usr/local/bin/xdg-open` that prefers `$BROWSER` (such as the VS Code browser helper) so the login page opens on your host machine. Set `configureBrowser` to `false` to skip it.

## Publishing

This repository uses a **GitHub Action** [workflow](.github/workflows/release.yaml) that publishes each Feature to GHCR (GitHub Container Registry).
Expand Down
6 changes: 6 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,16 @@ build-microsoft-security-devops-cli:
build-gitlab-ci-local:
just build-feature gitlab-ci-local

# Build Atlassian CLI (acli) feature
build-atlassian-jira-confluence-cli:
just build-feature atlassian-jira-confluence-cli

# Build all features
build-all:
just build-ohmyposh
just build-microsoft-security-devops-cli
just build-gitlab-ci-local
just build-atlassian-jira-confluence-cli

# Generate feature README.md files from devcontainer-feature.json and NOTES.md
generate-docs:
Expand All @@ -35,5 +40,6 @@ generate-docs:
clean:
rm -rf .devcontainer/ohmyposh
rm -rf .devcontainer/gitlab-ci-local
rm -rf .devcontainer/atlassian-jira-confluence-cli
rm -f .devcontainer/*.tgz
echo "✓ Cleaned local features"
42 changes: 42 additions & 0 deletions src/atlassian-jira-confluence-cli/NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
## About

The [Atlassian CLI](https://developer.atlassian.com/cloud/acli/) (`acli`) is Atlassian's official command line tool for working with **Jira** and **Confluence** Cloud (plus Atlassian Guard and Rovo Dev) directly from your terminal.

For more information, see: https://developer.atlassian.com/cloud/acli/

## How It Works

1. **Downloads the official binary** from `acli.atlassian.com` (the same rolling `latest` and versioned `-stable` archives Atlassian publishes)
2. **Installs to** `/usr/local/bin/acli` by default (configurable via `installPath`)
3. **Supports** both `amd64` and `arm64` architectures
4. **Installs an `xdg-open` shim** (when `configureBrowser` is `true`, the default) so the OAuth login opens in your host browser — see below

## Browser Login in a Dev Container

`acli auth login` opens an OAuth page by shelling out to `xdg-open`, which doesn't
honor `$BROWSER` and fails (or tries to launch a browser inside the container).
With `configureBrowser` enabled, this feature installs a small `xdg-open` shim at
`/usr/local/bin/xdg-open` that prefers `$BROWSER` (for example the VS Code browser
helper) and falls back to the real `xdg-open` otherwise, so the login page opens on
your host. Set `configureBrowser` to `false` to skip installing the shim.

## Usage

Authenticate once (interactive OAuth login):

```bash
acli auth login
```

Then work with Jira and Confluence, for example:

```bash
# List your Jira projects
acli jira project list

# View a Jira work item
acli jira workitem view --key PROJ-123

# Confluence commands
acli confluence --help
```
68 changes: 68 additions & 0 deletions src/atlassian-jira-confluence-cli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@

# Atlassian CLI for Jira & Confluence (atlassian-jira-confluence-cli)

Installs the Atlassian CLI (acli) for working with Jira and Confluence Cloud from the command line

## Example Usage

```json
"features": {
"ghcr.io/rosstaco/devcontainer-features/atlassian-jira-confluence-cli:1": {}
}
```

## Options

| Options Id | Description | Type | Default Value |
|-----|-----|-----|-----|
| version | Version of acli to install. Use 'latest' or a specific version like '1.3.21' | string | latest |
| installPath | Directory where the acli binary will be installed | string | /usr/local/bin |
| configureBrowser | Install an xdg-open shim in /usr/local/bin that prefers $BROWSER (e.g. the VS Code browser helper) so 'acli auth login' opens the OAuth page on your host instead of failing inside the container | boolean | true |

## About

The [Atlassian CLI](https://developer.atlassian.com/cloud/acli/) (`acli`) is Atlassian's official command line tool for working with **Jira** and **Confluence** Cloud (plus Atlassian Guard and Rovo Dev) directly from your terminal.

For more information, see: https://developer.atlassian.com/cloud/acli/

## How It Works

1. **Downloads the official binary** from `acli.atlassian.com` (the same rolling `latest` and versioned `-stable` archives Atlassian publishes)
2. **Installs to** `/usr/local/bin/acli` by default (configurable via `installPath`)
3. **Supports** both `amd64` and `arm64` architectures
4. **Installs an `xdg-open` shim** (when `configureBrowser` is `true`, the default) so the OAuth login opens in your host browser — see below

## Browser Login in a Dev Container

`acli auth login` opens an OAuth page by shelling out to `xdg-open`, which doesn't
honor `$BROWSER` and fails (or tries to launch a browser inside the container).
With `configureBrowser` enabled, this feature installs a small `xdg-open` shim at
`/usr/local/bin/xdg-open` that prefers `$BROWSER` (for example the VS Code browser
helper) and falls back to the real `xdg-open` otherwise, so the login page opens on
your host. Set `configureBrowser` to `false` to skip installing the shim.

## Usage

Authenticate once (interactive OAuth login):

```bash
acli auth login
```

Then work with Jira and Confluence, for example:

```bash
# List your Jira projects
acli jira project list

# View a Jira work item
acli jira workitem view --key PROJ-123

# Confluence commands
acli confluence --help
```


---

_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/rosstaco/devcontainer-features/blob/main/src/atlassian-jira-confluence-cli/devcontainer-feature.json). Add additional notes to a `NOTES.md`._
41 changes: 41 additions & 0 deletions src/atlassian-jira-confluence-cli/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"id": "atlassian-jira-confluence-cli",
"version": "1.0.0",
"name": "Atlassian CLI for Jira & Confluence",
"description": "Installs the Atlassian CLI (acli) for working with Jira and Confluence Cloud from the command line",
"documentationURL": "https://github.com/rosstaco/devcontainer-features/tree/main/src/atlassian-jira-confluence-cli",
"options": {
"version": {
"type": "string",
"proposals": [
"latest"
],
"default": "latest",
"description": "Version of acli to install. Use 'latest' or a specific version like '1.3.21'"
},
"installPath": {
"type": "string",
"default": "/usr/local/bin",
"description": "Directory where the acli binary will be installed"
},
"configureBrowser": {
"type": "boolean",
"default": true,
"description": "Install an xdg-open shim in /usr/local/bin that prefers $BROWSER (e.g. the VS Code browser helper) so 'acli auth login' opens the OAuth page on your host instead of failing inside the container"
}
},
"customizations": {
"vscode": {
"settings": {
"github.copilot.chat.codeGeneration.instructions": [
{
"text": "This dev container includes `acli`, the Atlassian CLI, pre-installed and available on the `PATH`. Use it to work with Jira and Confluence Cloud from the command line. Authenticate with `acli auth login` before running commands."
}
]
}
}
},
"installsAfter": [
"ghcr.io/devcontainers/features/common-utils"
]
}
113 changes: 113 additions & 0 deletions src/atlassian-jira-confluence-cli/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/bin/bash
set -e

# Atlassian CLI (acli) installation script for devcontainer features
# https://developer.atlassian.com/cloud/acli/

CLI_VERSION="${VERSION:-latest}"
INSTALL_PATH="${INSTALLPATH:-/usr/local/bin}"
CONFIGURE_BROWSER="${CONFIGUREBROWSER:-true}"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color

if [ "$(id -u)" -ne 0 ]; then
echo -e "${RED}Script must be run as root. Use sudo, su, or add \"USER root\" to your Dockerfile before running this script.${NC}"
exit 1
fi

apt_get_update() {
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update -y
fi
}

# Checks if packages are installed and installs them if not
check_packages() {
if ! dpkg -s "$@" > /dev/null 2>&1; then
apt_get_update
apt-get -y install --no-install-recommends "$@"
fi
}

echo -e "${GREEN}Installing Atlassian CLI (acli)...${NC}"

check_packages curl ca-certificates tar
echo "Finished setting up dependencies"

# Detect architecture using dpkg (acli publishes amd64 and arm64 builds)
arch=$(dpkg --print-architecture)
if [ "${arch}" != "amd64" ] && [ "${arch}" != "arm64" ]; then
echo -e "${RED}Unsupported architecture: ${arch}${NC}" >&2
echo -e "${RED}Only amd64 and arm64 are supported.${NC}" >&2
exit 1
fi
echo "Detected architecture: ${arch}"

# Build the download URL. 'latest' uses the rolling release path; a pinned
# version resolves to the versioned '<version>-stable' archive.
if [ "${CLI_VERSION}" = "latest" ]; then
download_url="https://acli.atlassian.com/linux/latest/acli_linux_${arch}.tar.gz"
else
# Normalize the version: drop any leading 'v' and ensure the '-stable' suffix
release="${CLI_VERSION#v}"
case "${release}" in
*-stable) ;;
*) release="${release}-stable" ;;
esac
download_url="https://acli.atlassian.com/linux/${release}/acli_${release}_linux_${arch}.tar.gz"
fi

echo "Downloading acli from ${download_url}..."

tmp_dir="$(mktemp -d)"
cleanup() { rm -rf "${tmp_dir}"; }
trap cleanup EXIT

if ! curl -fsSL "${download_url}" -o "${tmp_dir}/acli.tar.gz"; then
echo -e "${RED}Failed to download acli from ${download_url}${NC}" >&2
echo -e "${RED}Check that the requested version '${CLI_VERSION}' exists.${NC}" >&2
exit 1
fi

# The archive contains a single '<name>/acli' entry; strip the top-level dir
tar -xzf "${tmp_dir}/acli.tar.gz" --strip-components=1 -C "${tmp_dir}"

if [ ! -f "${tmp_dir}/acli" ]; then
echo -e "${RED}acli binary not found in downloaded archive${NC}" >&2
exit 1
fi

mkdir -p "${INSTALL_PATH}"
install -m 0755 "${tmp_dir}/acli" "${INSTALL_PATH}/acli"

# Verify installation
if ! command -v acli &> /dev/null && [ ! -x "${INSTALL_PATH}/acli" ]; then
echo -e "${RED}acli installation failed - binary not found${NC}" >&2
exit 1
fi

INSTALLED_VERSION=$("${INSTALL_PATH}/acli" --version 2>&1 | head -n 1 || true)
echo -e "${GREEN}acli installed successfully to ${INSTALL_PATH}/acli: ${INSTALLED_VERSION}${NC}"

# acli's OAuth login shells out to 'xdg-open' rather than honoring $BROWSER,
# which fails (or pops an in-container browser) inside a dev container. Install a
# shim on the PATH that prefers $BROWSER (e.g. VS Code's browser helper) and
# falls back to the real xdg-open otherwise.
if [ "${CONFIGURE_BROWSER}" = "true" ]; then
echo "Installing xdg-open shim that prefers \$BROWSER..."
cat > /usr/local/bin/xdg-open <<'SHIM'
#!/bin/sh
[ -n "$BROWSER" ] && [ -x "$BROWSER" ] && exec "$BROWSER" "$@"
exec /usr/bin/xdg-open "$@"
SHIM
chmod 0755 /usr/local/bin/xdg-open
fi

echo ""
echo "The 'acli' command is now available."
echo "Authenticate with 'acli auth login' to start working with Jira and Confluence."
echo "For more information: https://developer.atlassian.com/cloud/acli/"
Loading
Loading