Skip to content

Conversation

@viliakov
Copy link
Contributor

@viliakov viliakov commented Aug 26, 2025

Summary

  • Implemented the stackpack package subcommand that creates zip files from stackpack directories. This command packages all required stackpack files and directories into a properly named zip archive for distribution and deployment.
  • STS_EXPERIMENTAL_STACKPACK_SCAFFOLD environment variable renamed to STS_EXPERIMENTAL_STACKPACK

Features

  • Zip file creation: Packages stackpack directories into <stackpack_name>-.zip format
  • HOCON configuration parsing: Extracts name and version from stackpack.conf files using dedicated HOCON parser
  • Flexible output options: Supports custom archive file paths via -f/--archive-file flag
  • Directory validation: Validates presence of required stackpack files and directories:
    • provisioning/ (directory)
    • README.md (file)
    • resources/ (directory)
    • stackpack.conf (file)
  • Force overwrite: --force flag to overwrite existing zip files

Usage Examples

Package stackpack in current directory

sts stackpack package

Package specific stackpack directory

sts stackpack package -d ./my-stackpack

Package with custom archive filename

sts stackpack package -f my-custom-archive.zip

Force overwrite existing zip file

sts stackpack package --force

@viliakov
Copy link
Contributor Author

viliakov commented Aug 26, 2025

Stackpack Package CLI Command - Complete Test Results

Prerequisites

  • Set experimental flag: export STS_EXPERIMENTAL_STACKPACK=1

Test Environment Setup

  • Ensure you have a valid stackpack directory for testing (e.g., ./my-awesome-stackpack) ✅
  • Verify stackpack directory contains required files:
    • stackpack.conf (HOCON format with name and version) ✅
    • provisioning/ directory ✅
    • README.md file ✅
    • resources/ directory ✅

Test Execution Results

1. Basic Package Command

Default Functionality

Test: STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package (from within stackpack directory)

✅ ✓ Stackpack packaged successfully!

Stackpack: my-awesome-stackpack (v0.0.1)
Zip file: /Users/viliakov/Workspace/src/github/stackstate-cli/my-awesome-stackpack/my-awesome-stackpack-0.0.1.zip
  • Packages current directory as stackpack ✅
  • Creates zip file in current directory ✅
  • Zip file named <stackpack_name>-<version>.zip
  • Shows success message with stackpack name, version, and zip file path ✅
  • Zip file contains all required files and directories ✅

Package Specific Directory

Test: rm -f *zip ; STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -d ./my-awesome-stackpack

✅ ✓ Stackpack packaged successfully!

Stackpack: my-awesome-stackpack (v0.0.1)
Zip file: /Users/viliakov/Workspace/src/github/stackstate-cli/my-awesome-stackpack-0.0.1.zip
  • Packages specified directory as stackpack ✅
  • Creates zip file in current directory (not in stackpack directory) ✅
  • Uses -d/--stackpack-directory flag to specify source directory ✅

Verify Zip Contents

Test: unzip -l my-awesome-stackpack-0.0.1.zip

Archive:  my-awesome-stackpack-0.0.1.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      587  00-00-1980 00:00   provisioning/metricbindings.sty
     1112  00-00-1980 00:00   provisioning/monitors.sty
        0  00-00-1980 00:00   provisioning/remediation-hints/
      479  00-00-1980 00:00   provisioning/remediation-hints/node-memory-pressure.md.hbs
       89  00-00-1980 00:00   provisioning/stackpack.sty
     4352  00-00-1980 00:00   README.md
      105  00-00-1980 00:00   resources/deprovisioning.md
      116  00-00-1980 00:00   resources/error.md
      123  00-00-1980 00:00   resources/installed.md
    17408  00-00-1980 00:00   resources/logo.png
      107  00-00-1980 00:00   resources/notinstalled.md
       74  00-00-1980 00:00   resources/overview.md
      103  00-00-1980 00:00   resources/provisioning.md
      125  00-00-1980 00:00   resources/waitingfordata.md
     1835  00-00-1980 00:00   stackpack.conf
---------                     -------
    26615                     15 files
  • Contains provisioning/ directory with all subdirectories and files ✅
  • Contains README.md file ✅
  • Contains resources/ directory with all subdirectories and files ✅
  • Contains stackpack.conf file ✅
  • Directory structure is preserved ✅
  • No .git directories or other zip files included ✅

2. Custom Archive File Flag

Custom Filename

Test: rm -f *zip ; STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -f custom-archive.zip -d ./my-awesome-stackpack

✅ ✓ Stackpack packaged successfully!

Stackpack: my-awesome-stackpack (v0.0.1)
Zip file: /Users/viliakov/Workspace/src/github/stackstate-cli/custom-archive.zip
  • Creates zip file with custom name ✅
  • Shows success message with custom filename ✅
  • File created in current directory ✅

Custom Path

Test: mkdir -p ./dist && STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -f ./dist/my-package.zip -d ./my-awesome-stackpack

✅ ✓ Stackpack packaged successfully!

Stackpack: my-awesome-stackpack (v0.0.1)
Zip file: /Users/viliakov/Workspace/src/github/stackstate-cli/dist/my-package.zip
  • Creates zip file in specified directory ✅
  • Creates output directory if it doesn't exist ✅
  • Shows success message with full path ✅

3. Force Flag Functionality

Without Force Flag

Test: rm -f *zip ; STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -d ./my-awesome-stackpack (run twice)

First run:

✅ ✓ Stackpack packaged successfully!

Stackpack: my-awesome-stackpack (v0.0.1)
Zip file: /Users/viliakov/Workspace/src/github/stackstate-cli/my-awesome-stackpack-0.0.1.zip

Second run:

❌ Zip file already exists: /Users/viliakov/Workspace/src/github/stackstate-cli/my-awesome-stackpack-0.0.1.zip (use --force to overwrite)
exit status 9
  • First run succeeds ✅
  • Second run shows error: "zip file already exists" with --force suggestion ✅
  • No file overwritten ✅

With Force Flag

Test: STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package --force -d ./my-awesome-stackpack

✅ ✓ Stackpack packaged successfully!

Stackpack: my-awesome-stackpack (v0.0.1)
Zip file: /Users/viliakov/Workspace/src/github/stackstate-cli/my-awesome-stackpack-0.0.1.zip
  • Overwrites existing zip file without prompt ✅
  • Shows success message ✅
  • File timestamp updated ✅

4. Output Formats

JSON Output

Test: rm -f *zip ; STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -o json -d ./my-awesome-stackpack

{
  "source_dir": "/Users/viliakov/Workspace/src/github/stackstate-cli/my-awesome-stackpack",
  "stackpack_name": "my-awesome-stackpack",
  "stackpack_version": "0.0.1",
  "success": true,
  "zip_file": "/Users/viliakov/Workspace/src/github/stackstate-cli/my-awesome-stackpack-0.0.1.zip"
}
  • Returns valid JSON format ✅
  • Contains fields: success, stackpack_name, stackpack_version, zip_file, source_dir ✅
  • No plain text output shown ✅

Text Output (Default)

Test: rm -f *zip ; STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -o text -d ./my-awesome-stackpack

✅ ✓ Stackpack packaged successfully!

Stackpack: my-awesome-stackpack (v0.0.1)
Zip file: /Users/viliakov/Workspace/src/github/stackstate-cli/my-awesome-stackpack-0.0.1.zip
  • Shows formatted text output with success message ✅
  • Displays stackpack name and version ✅
  • Shows zip file path ✅

5. HOCON Configuration Parsing

Valid HOCON File

Verify stackpack.conf format:

# schemaVersion -- Stackpack specification version.
schemaVersion = "2.0"
# name -- Name of the StackPack. This is what is used to uniquely identify the StackPack.
name = "my-awesome-stackpack"
# displayName -- Name that's displayed on both the StackPack listing page and on the title of the StackPack page.
displayName = "This is my awesome stackpack"
# version -- Semantic version of the StackPack. StackPacks with the same major version are considered compatible.
version = "0.0.1"

Test: rm -f *zip ; STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -d ./my-awesome-stackpack

✅ ✓ Stackpack packaged successfully!

Stackpack: my-awesome-stackpack (v0.0.1)
Zip file: /Users/viliakov/Workspace/src/github/stackstate-cli/my-awesome-stackpack-0.0.1.zip
  • Correctly extracts name and version from HOCON ✅
  • Zip file named using extracted values ✅

6. Validation and Error Handling

Missing Required Files

Test: Create test directory missing provisioning/
Command: STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -d ./incomplete-stackpack

❌ Required stackpack item not found: provisioning
exit status 3
  • Shows error: "required stackpack item not found: provisioning" ✅

Test: Create test directory missing README.md
Command: STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -d ./incomplete-stackpack

❌ Required stackpack item not found: README.md
exit status 3
  • Shows error: "required stackpack item not found: README.md" ✅

Invalid stackpack.conf File

Test: Create invalid stackpack.conf (malformed HOCON)
Command: STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -d ./invalid-stackpack

❌ Failed to parse stackpack.conf: failed to parse stackpack.conf file: invalid config object! at: 2:1, parenthesis do not match
exit status 9
  • Shows stackpack.conf parsing error ✅

Test: Create stackpack.conf missing name field
Command: STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -d ./missing-name-stackpack

❌ Failed to parse stackpack.conf: name not found in stackpack.conf
exit status 9
  • Shows error: "name not found in stackpack.conf" ✅

Invalid Directories

Test: STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -d ./nonexistent-directory

❌ Failed to parse stackpack.conf: failed to read file: open /Users/viliakov/Workspace/src/github/stackstate-cli/nonexistent-directory/stackpack.conf: no such file or directory
exit status 9
  • Shows appropriate error about directory not existing ✅

7. Help and Usage

Command Help

Test: STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package --help

Package a stackpack into a zip file.

Creates a zip file containing all required stackpack files and directories:
- provisioning/ (directory)
- README.md (file)
- resources/ (directory)
- stackpack.conf (file)

The zip file is named <stackpack_name>-<version>.zip where the name and
version are extracted from stackpack.conf and created in the current directory.

Usage:
  sts stackpack package [flags]

Examples:
# Package stackpack in current directory
sts stackpack package

# Package specific stackpack directory
sts stackpack package -d ./my-stackpack

# Package with custom archive filename
sts stackpack package -f my-custom-archive.zip

# Force overwrite existing zip file
sts stackpack package --force

Flags:
  -f, --archive-file string          Path to the zip file to create (defaults to <stackpack_name>-<version>.zip in current directory)
      --force                        Overwrite existing zip file without prompting
  -h, --help                         help for package
  -d, --stackpack-directory string   Path to stackpack directory (defaults to current directory)
  • Shows usage information ✅
  • Lists all flags with descriptions: -d/--stackpack-directory, -f/--archive-file, --force
  • Shows examples of command usage ✅
  • Mentions default behavior (current directory, auto-naming) ✅

Parent Command Help

Test: STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack --help

Available Commands:
  confirm-manual-steps Confirm manual steps of StackPack
  describe             Describe a StackPack
  install              Install a StackPack
  list                 List stackpacks
  list-instances       List installed instances of a StackPack
  list-parameters      List all parameters
  package              Package a stackpack into a zip file
  scaffold             Create a stackpack skeleton from a template
  uninstall            Uninstall instances of a StackPack
  upgrade              Upgrade a StackPack
  upload               Upload a stackpack
  • Lists package as available subcommand under experimental features ✅
  • Shows brief description ✅

Without Experimental Flag

Test: go run main.go stackpack --help (without STS_EXPERIMENTAL_STACKPACK)

Available Commands:
  confirm-manual-steps Confirm manual steps of StackPack
  describe             Describe a StackPack
  install              Install a StackPack
  list                 List stackpacks
  list-instances       List installed instances of a StackPack
  list-parameters      List all parameters
  uninstall            Uninstall instances of a StackPack
  upgrade              Upgrade a StackPack
  upload               Upload a stackpack
  • Does NOT show package command (experimental feature disabled) ✅

Test Results Summary

All tests passed successfully. The stackpack package command:

  • ✅ Correctly packages stackpack directories into zip files
  • ✅ Properly extracts name and version from HOCON configuration
  • ✅ Validates required files and directories
  • ✅ Handles custom archive paths and filenames
  • ✅ Supports force overwrite functionality
  • ✅ Provides both JSON and text output formats
  • ✅ Shows appropriate error messages for invalid inputs
  • ✅ Requires experimental flag for access
  • ✅ Includes comprehensive help documentation

Copy link
Contributor

@deontaljaard deontaljaard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@viliakov viliakov merged commit 87afbb8 into main Aug 27, 2025
5 checks passed
@viliakov viliakov deleted the STAC-22609 branch August 27, 2025 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants