Skip to content

Commit f32b81a

Browse files
committed
chore: prepare release
1 parent 2f920c8 commit f32b81a

File tree

9 files changed

+475
-102
lines changed

9 files changed

+475
-102
lines changed

.claude/settings.local.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(go test:*)",
5+
"Bash(go fmt:*)",
6+
"Bash(go vet:*)",
7+
"Bash(go build:*)"
8+
],
9+
"deny": [],
10+
"ask": []
11+
}
12+
}

.github/workflows/ci.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Set up Go
16+
uses: actions/setup-go@v4
17+
with:
18+
go-version: '1.24'
19+
20+
- name: Run tests
21+
run: go test ./...
22+
23+
- name: Run go vet
24+
run: go vet ./...
25+
26+
- name: Run go fmt
27+
run: |
28+
if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then
29+
echo "Code is not formatted properly:"
30+
gofmt -s -l .
31+
exit 1
32+
fi
33+
34+
- name: Build
35+
run: go build -v ./...

.github/workflows/release.yml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: write
11+
12+
jobs:
13+
build:
14+
name: Build and Release
15+
runs-on: ubuntu-latest
16+
strategy:
17+
matrix:
18+
include:
19+
- os: linux
20+
arch: amd64
21+
goos: linux
22+
goarch: amd64
23+
- os: linux
24+
arch: arm64
25+
goos: linux
26+
goarch: arm64
27+
- os: darwin
28+
arch: amd64
29+
goos: darwin
30+
goarch: amd64
31+
- os: darwin
32+
arch: arm64
33+
goos: darwin
34+
goarch: arm64
35+
- os: windows
36+
arch: amd64
37+
goos: windows
38+
goarch: amd64
39+
- os: windows
40+
arch: arm64
41+
goos: windows
42+
goarch: arm64
43+
44+
steps:
45+
- uses: actions/checkout@v4
46+
47+
- name: Set up Go
48+
uses: actions/setup-go@v4
49+
with:
50+
go-version: '1.24'
51+
52+
- name: Build binary
53+
env:
54+
GOOS: ${{ matrix.goos }}
55+
GOARCH: ${{ matrix.goarch }}
56+
CGO_ENABLED: 0
57+
run: |
58+
if [ "${{ matrix.goos }}" = "windows" ]; then
59+
go build -ldflags="-s -w" -o jh-${{ matrix.os }}-${{ matrix.arch }}.exe .
60+
else
61+
go build -ldflags="-s -w" -o jh-${{ matrix.os }}-${{ matrix.arch }} .
62+
fi
63+
64+
- name: Upload artifact
65+
uses: actions/upload-artifact@v3
66+
with:
67+
name: jh-${{ matrix.os }}-${{ matrix.arch }}
68+
path: jh-*
69+
70+
release:
71+
needs: build
72+
runs-on: ubuntu-latest
73+
if: startsWith(github.ref, 'refs/tags/')
74+
75+
steps:
76+
- name: Download all artifacts
77+
uses: actions/download-artifact@v3
78+
79+
- name: Create Release
80+
uses: softprops/action-gh-release@v1
81+
with:
82+
files: |
83+
**/jh-*
84+
generate_release_notes: true
85+
env:
86+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
jh

README.md

Lines changed: 204 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,204 @@
1-
# gojuliahub
1+
# JuliaHub CLI (`jh`)
2+
3+
A command-line interface for interacting with JuliaHub, a platform for Julia computing that provides dataset management, job execution, project management, Git integration, and package hosting capabilities.
4+
5+
## Features
6+
7+
- **Authentication**: OAuth2 device flow authentication with JWT token handling
8+
- **Dataset Management**: List, download, upload, and check status of datasets
9+
- **Project Management**: List and filter projects using GraphQL API
10+
- **Git Integration**: Clone, push, fetch, and pull with automatic JuliaHub authentication
11+
- **Julia Integration**: Install Julia and run with JuliaHub package server configuration
12+
- **User Management**: Display user information and profile details
13+
14+
## Installation
15+
16+
### Download Binary
17+
18+
Download the latest release from the [GitHub releases page](https://github.com/yourusername/jh/releases).
19+
20+
Available for:
21+
22+
- Linux (amd64, arm64)
23+
- macOS (amd64, arm64)
24+
- Windows (amd64, arm64)
25+
26+
### Build from Source
27+
28+
```bash
29+
git clone https://github.com/yourusername/jh
30+
cd jh
31+
go build -o jh .
32+
```
33+
34+
## Quick Start
35+
36+
1. **Authenticate with JuliaHub:**
37+
38+
```bash
39+
jh auth login
40+
```
41+
42+
2. **List your datasets:**
43+
44+
```bash
45+
jh dataset list
46+
```
47+
48+
3. **List your projects:**
49+
50+
```bash
51+
jh project list
52+
```
53+
54+
4. **Clone a project:**
55+
56+
```bash
57+
jh clone username/project-name
58+
```
59+
60+
5. **Setup Git credential helper** (recommended for seamless Git operations):
61+
```bash
62+
jh git-credential setup
63+
# Now you can use standard Git commands with JuliaHub repositories
64+
git clone https://juliahub.com/git/projects/username/project.git
65+
```
66+
67+
## Commands
68+
69+
### Authentication (`jh auth`)
70+
71+
- `jh auth login` - Login to JuliaHub using OAuth2 device flow
72+
- `jh auth refresh` - Refresh authentication token
73+
- `jh auth status` - Show authentication status
74+
- `jh auth env` - Print environment variables for authentication
75+
76+
### Dataset Management (`jh dataset`)
77+
78+
- `jh dataset list` - List all accessible datasets
79+
- `jh dataset download <dataset-id> [version] [local-path]` - Download a dataset
80+
- `jh dataset upload [dataset-id] <file-path>` - Upload a dataset
81+
- `jh dataset status <dataset-id> [version]` - Show dataset status
82+
83+
### Project Management (`jh project`)
84+
85+
- `jh project list` - List all accessible projects
86+
- `jh project list --user` - List only your projects
87+
- `jh project list --user <username>` - List specific user's projects
88+
89+
### Git Credential Helper (Recommended)
90+
91+
- `jh git-credential setup` - Configure Git to use JuliaHub authentication
92+
- After setup, use standard Git commands: `git clone`, `git push`, `git pull`
93+
94+
### Git Operations
95+
96+
- `jh clone <username/project> [local-path]` - Clone a JuliaHub project by username/project name
97+
- `jh push [git-args...]` - Push with authentication
98+
- `jh fetch [git-args...]` - Fetch with authentication
99+
- `jh pull [git-args...]` - Pull with authentication
100+
101+
### Julia Integration
102+
103+
- `jh julia install` - Install Julia programming language
104+
- `jh run` - Start Julia with JuliaHub configuration
105+
106+
### User Information (`jh user`)
107+
108+
- `jh user info` - Show detailed user information
109+
110+
## Configuration
111+
112+
Configuration is stored in `~/.juliahub` with 0600 permissions. The file contains:
113+
114+
- Server configuration
115+
- Authentication tokens (access, refresh, ID tokens)
116+
- User information (name, email)
117+
118+
Default server: `juliahub.com`
119+
120+
## Examples
121+
122+
### Dataset Operations
123+
124+
```bash
125+
# List datasets
126+
jh dataset list
127+
128+
# Download latest version of a dataset
129+
jh dataset download my-dataset
130+
131+
# Download specific version
132+
jh dataset download username/dataset-name v2
133+
134+
# Upload new dataset
135+
jh dataset upload --new ./my-data.tar.gz
136+
137+
# Upload new version to existing dataset
138+
jh dataset upload my-dataset ./updated-data.tar.gz
139+
```
140+
141+
### Project Operations
142+
143+
```bash
144+
# List all projects you have access to
145+
jh project list
146+
147+
# List only your projects
148+
jh project list --user
149+
150+
# List projects by specific user
151+
jh project list --user alice
152+
```
153+
154+
### Git Workflow
155+
156+
```bash
157+
# Option 1: Use JuliaHub CLI wrapper commands (resolves uuids for you)
158+
jh clone alice/my-project
159+
cd my-project
160+
# Make changes...
161+
jh push
162+
163+
# Option 2: Use Git credential helper (recommended)
164+
jh git-credential setup
165+
git clone https://juliahub.com/git/projects/uuid
166+
cd my-project
167+
# Make changes...
168+
git push
169+
```
170+
171+
Note: It's recommended to use the git-credential helper, but you can still
172+
clone using `jh clone username/project-name`; otherwise you need the project's uuid
173+
174+
## Architecture
175+
176+
- **Built with Go** using the Cobra CLI framework
177+
- **Authentication**: OAuth2 device flow with JWT token management
178+
- **APIs**: REST API for datasets, GraphQL API for projects and user info
179+
- **Git Integration**: Seamless authentication via HTTP headers or credential helper
180+
- **Cross-platform**: Supports Windows, macOS, and Linux
181+
182+
## Development
183+
184+
### Build and Test
185+
186+
```bash
187+
# Run tests
188+
go test ./...
189+
190+
# Build
191+
go build -o jh .
192+
193+
# Code quality checks
194+
go fmt ./...
195+
go vet ./...
196+
```
197+
198+
### Contributing
199+
200+
1. Fork the repository
201+
2. Create a feature branch
202+
3. Make changes with tests
203+
4. Run `go fmt ./...` and `go vet ./...`
204+
5. Submit a pull request

auth_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestParseJWTClaims(t *testing.T) {
8+
// Test with malformed token
9+
_, err := decodeJWT("invalid.token")
10+
if err == nil {
11+
t.Error("decodeJWT should fail with malformed token")
12+
}
13+
14+
// Test with empty token
15+
_, err = decodeJWT("")
16+
if err == nil {
17+
t.Error("decodeJWT should fail with empty token")
18+
}
19+
}

jh

-9.5 MB
Binary file not shown.

0 commit comments

Comments
 (0)