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 CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

## v1.0.0 — 2026-04-27

### Features

- **Persist all settings to `.env`** — Organization, project, PAT, API version, default version, and default platform are now saved to and loaded from a `.env` file.
- **First-time setup guidance** — README includes clear instructions for configuring org, project, and PAT on first launch.

### UX Improvements

- **Cleaner Settings dialog** — Removed API version, default version, and default platform fields from Settings; version and platform are set directly in the main UI.
- **Scripts moved to `scripts/` folder** — `build.bat` and `run.bat` relocated to `scripts/` for better project organization.

### Housekeeping

- **Removed hardcoded defaults** — Organization, project, and default version are no longer hardcoded in config; all values come from `.env`.
- **Design credit** — Added acknowledgement to [VoltAgent/awesome-design-md](https://github.com/VoltAgent/awesome-design-md) in README.

---

## v0.1.3 — 2026-04-22

### Features
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ python -m search_artifact_app
## Building the Executable

```bash
build.bat
scripts\build.bat
```

The output will be at `dist\ArtifactLens\ArtifactLens.exe`.
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,28 @@ git clone https://github.com/william051200/azure-artifacts-search.git
cd azure-artifacts-search
```

Double-click **`run.bat`** — it installs dependencies and launches the app automatically.
Double-click **`scripts/run.bat`** — it installs dependencies and launches the app automatically.

### Option C — Build the executable yourself

1. Double-click **`build.bat`** (requires Python for the one-time build)
1. Double-click **`scripts/build.bat`** (requires Python for the one-time build)
2. Find the output at `dist\ArtifactLens\ArtifactLens.exe`
3. Share the entire `dist\ArtifactLens\` folder — no Python required on target machines

## First-Time Setup

1. Launch the app and click **⚙ Settings**
2. Fill in your **Organization** and **Project** name from Azure DevOps
3. For private feeds, enter your **Personal Access Token (PAT)**
4. Click **Save** — settings are stored locally in a `.env` file

## Usage

1. Enter a version (e.g. `26.2.10196`)
1. Enter a version (e.g. `1.0.0`)
2. Optionally set a **feed filter**, **platform** (Android / MacIOS), or toggle search options
3. Click **Search**
4. Double-click a result to open the package in Azure DevOps

For private feeds, set your PAT in **⚙ Settings** inside the app.
## Acknowledgements

UI design inspired by [VoltAgent/awesome-design-md](https://github.com/VoltAgent/awesome-design-md).
File renamed without changes.
File renamed without changes.
16 changes: 9 additions & 7 deletions search_artifact_app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
from dotenv import load_dotenv

from search_artifact_app.config import (
ORG, PROJECT, API_VERSION,
API_VERSION,
build_base_url, build_artifact_url, build_feed_url, build_nuget_source_xml, PROTOCOL_TYPE_MAP,
DEFAULT_VERSION, DEFAULT_THREADS, DEFAULT_PLATFORM, PLATFORM_OPTIONS,
DEFAULT_THREADS, DEFAULT_PLATFORM, PLATFORM_OPTIONS,
WINDOW_SIZE, WINDOW_MIN_SIZE, APP_VERSION, MAX_THREADS,
)
from search_artifact_app.theme import (
Expand Down Expand Up @@ -64,11 +64,13 @@ def __init__(self):
self._feeds_loading = threading.Event()

load_dotenv()
self.org = os.getenv("AZURE_DEVOPS_ORG", ORG)
self.project = os.getenv("AZURE_DEVOPS_PROJECT", PROJECT)
self.api_version = API_VERSION
self.org = os.getenv("AZURE_DEVOPS_ORG", "")
self.project = os.getenv("AZURE_DEVOPS_PROJECT", "")
self.api_version = os.getenv("API_VERSION", API_VERSION)
pat_env = os.getenv("AZURE_DEVOPS_PAT", "")
self.pat = "" if pat_env.startswith("<") else pat_env
self.default_platform = os.getenv("DEFAULT_PLATFORM", DEFAULT_PLATFORM)
self.default_version = os.getenv("DEFAULT_VERSION", "")

self._build_ui()
self._center_window()
Expand Down Expand Up @@ -159,7 +161,7 @@ def _build_input_card(self):

ver_frame = tk.Frame(row1, bg=IVORY)
ver_frame.pack(side="left", fill="x", expand=True, padx=(0, 10))
self.version_entry = self._make_labeled_entry(ver_frame, "VERSION", DEFAULT_VERSION)
self.version_entry = self._make_labeled_entry(ver_frame, "VERSION", self.default_version)

feed_frame = tk.Frame(row1, bg=IVORY)
feed_frame.pack(side="left", fill="x", expand=True, padx=(0, 10))
Expand All @@ -171,7 +173,7 @@ def _build_input_card(self):
platform_frame, text="PLATFORM", font=FONT_SANS_LABEL_BOLD,
bg=IVORY, fg=STONE_GRAY, anchor="w",
).pack(fill="x")
self.platform_var = tk.StringVar(value=DEFAULT_PLATFORM)
self.platform_var = tk.StringVar(value=self.default_platform)
self.platform_combo = ttk.Combobox(
platform_frame, textvariable=self.platform_var,
values=PLATFORM_OPTIONS,
Expand Down
5 changes: 1 addition & 4 deletions search_artifact_app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,17 @@

import os

ORG = "dnceng"
PROJECT = "public"
API_VERSION = "7.1-preview.1"

# ── App defaults ──
DEFAULT_VERSION = "26.2.10196"

DEFAULT_THREADS = os.cpu_count() or 8
MAX_THREADS = DEFAULT_THREADS
DEFAULT_PLATFORM = "Android"
PLATFORM_OPTIONS = ["No filter", "Android", "MacIOS"]
WINDOW_SIZE = "1200x720"
WINDOW_MIN_SIZE = (900, 500)
APP_VERSION = "0.1.3"
APP_VERSION = "1.0.0"


def build_base_url(org: str, project: str) -> str:
Expand Down
13 changes: 11 additions & 2 deletions search_artifact_app/settings_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ def open_settings(parent) -> None:

org_entry = _make_field(form, "ORGANIZATION", parent.org)
project_entry = _make_field(form, "PROJECT", parent.project)
api_entry = _make_field(form, "API VERSION", parent.api_version)

# PAT field with show/hide toggle
pat_header = tk.Frame(form, bg=PARCHMENT)
Expand Down Expand Up @@ -87,8 +86,9 @@ def _toggle_show():
def _save():
parent.org = org_entry.get().strip() or parent.org
parent.project = project_entry.get().strip() or parent.project
parent.api_version = api_entry.get().strip() or parent.api_version
parent.pat = pat_entry.get().strip()
parent.default_version = parent.version_entry.get().strip()
parent.default_platform = parent.platform_var.get()
parent.nav_label.config(text=f"{parent.org} / {parent.project}")

# Persist settings to the .env file
Expand All @@ -102,6 +102,15 @@ def _save():
"\n",
"# Azure DevOps Project Name\n",
f"AZURE_DEVOPS_PROJECT={parent.project}\n",
"\n",
"# Azure DevOps API Version\n",
f"API_VERSION={parent.api_version}\n",
"\n",
"# Default search version\n",
f"DEFAULT_VERSION={parent.default_version}\n",
"\n",
"# Default platform filter\n",
f"DEFAULT_PLATFORM={parent.default_platform}\n",
]
with open(env_path, "w", encoding="utf-8") as f:
f.writelines(lines)
Expand Down
Loading