JiraPS PowerShell Module

repository·master·Indexed 43 days ago

https://github.com/atlassianps/jiraps

A Windows PowerShell module for interacting with Atlassian Jira via its REST API. It provides a consistent PowerShell experience for managing Jira resources, including support for Jira Cloud and Jira Data Center instances.

Tokens
69.5K
Snippets
244
Records
321
Agent score
40%

What's inside JiraPS

  1. Overview of JiraPS Integration Test Tracks

    master

    JiraPS integration tests verify functionality against real Jira APIs using two distinct tracks. The track is selected via the CI_JIRA_TYPE environment variable.

    Cloud Track (Default)

    • Target: A live Jira Cloud instance.
    • Authentication: API token + email.
    • Configuration: Requires JIRA_CLOUD_* secrets/environment variables.
    • Usage: Best for testing ADF v3, accountId-shaped fixtures, and /rest/api/3/* endpoints.

    Server Track

    • Target: A Dockerized Jira Data Center instance using the moveworkforward/atlas-run-standalone:jira-11 image.
    • Authentication: Basic auth (admin/admin).
    • Configuration: Triggered by setting CI_JIRA_TYPE=Server.
    • Usage: Best for testing DC-specific identity models and basic-auth-only flows.
  2. Use the converter function pattern for private function tests

    master

    When writing unit tests for private (internal) JiraPS functions that perform pure data manipulation, use the converter function pattern. This pattern is specifically designed for functions that:

    • Transform data (e.g., ConvertTo-*, ConvertFrom-*)
    • Parse JSON responses into PowerShell objects
    • Perform pure data manipulation without external calls
    • Format or encode/decode data

    Unlike public CRUD tests, these tests do not require mocks or signature tests because they focus on data transformation accuracy rather than API interaction.

    # See ConvertTo-JiraAttachment.Unit.Tests.ps1 for a complete example
  3. How to test public JiraPS functions

    master

    Public (exported) JiraPS functions follow a CRUD function pattern. These tests are used for functions that interact with external systems, such as those making JIRA API calls (e.g., Get-*, Set-*, New-*, Remove-*, Add-*).

    Unlike private converter tests, public function tests must:

    • Use extensive mocking of API calls (specifically Invoke-JiraMethod).
    • Verify parameter signatures and input validation.
    • Focus on error handling, edge cases, and interactions with external systems.
  4. Manage persistent sessions with New-JiraSession

    master

    JiraPS supports persistent sessions. Once you call New-JiraSession, the authentication is stored in the module's runtime, allowing you to run subsequent commands without passing credentials every time.

    Important Lifecycle Notes:

    • The session is stored in the current PowerShell runtime.
    • The session is not available in a new PowerShell session or if the module is reloaded.
    • For advanced use cases, you can pass custom headers using the -Headers parameter.
    # Example: Creating a session for Data Center
    New-JiraSession -PersonalAccessToken $pat
    
    # Subsequent commands do not need credentials
    Get-JiraIssue TEST-01
    
    # Custom Authorization Headers
    $headers = @{ Authorization = "Bearer $token" }
    New-JiraSession -Headers $headers
  5. How DeploymentType works in JiraPS

    master

    The DeploymentType property (returned as part of the AtlassianPS.JiraPS.ServerInfo object) is a critical internal flag used by JiraPS to adapt API calls for different Jira platforms.

    • Cloud: Indicates a Jira Cloud instance. JiraPS will use Cloud-specific logic, such as using accountId instead of username and targeting API v3 endpoints.
    • Server: Indicates a Jira Data Center or Server instance.

    Note on Defaults: If the API response lacks a deploymentType field (common in older Jira Server versions) or if the API call fails, JiraPS defaults the DeploymentType to Server to allow operations to continue.

    (Get-JiraServerInformation).DeploymentType
  6. How to identify and use transitions with Invoke-JiraIssueTransition

    master

    To transition an issue dynamically, you should first retrieve the issue and filter its available transitions based on the desired target status.

    1. Use Get-JiraIssue to get the issue object.
    2. Expand the Transition property.
    3. Filter for the transition where ResultStatus.Name matches your target status.
    4. Pass that transition object to Invoke-JiraIssueTransition.
    $transition = Get-JiraIssue -Issue TEST-01 | Select-Object -ExpandProperty Transition | ? {$_.ResultStatus.Name -eq 'In Progress'}
    Invoke-JiraIssueTransition -Issue TEST-01 -Transition $transition
  7. Use custom fields with the -Fields parameter

    master

    The -Fields parameter allows you to provide additional custom fields when creating an issue. It accepts a PSObject (typically a hashtable).

    Resolution Logic:

    1. JiraPS first resolves field names against the create metadata returned by Get-JiraIssueCreateMetadata for the specific project and issue type. This prevents ambiguity if duplicate custom-field names exist across different projects.
    2. If the key is not found in the scoped metadata, it falls back to the global Get-JiraField catalogue.

    Platform Specific Behavior:

    • Jira Cloud: String values for rich-text fields (like description, environment, or custom textareas with schema type doc) are automatically interpreted as Markdown and converted to Atlassian Document Format (ADF). For full control over complex structures, you can pass a pre-built ADF document (hashtable/object) directly.
    • Jira Server / Data Center: Values are forwarded verbatim as provided.
  8. Working with resolved objects in JiraPS

    master

    Objects returned by cmdlets are real class instances. Key behaviors include:

    • Type Safety: They work naturally with type checks and tab completion.
    • String Representation: ToString() returns the canonical identifier, making them user-friendly in logs, interpolation, and pipelines.
    • Equality: Identifier-based equality and comparisons work correctly with -eq, Sort-Object -Unique, and as hashtable keys.

    Best Practice: If you need properties not modeled on a specific class, query the relevant endpoint/cmdlet to inspect the payload shape. Prefer explicit property access for stable fields rather than relying on display formatting.

  9. Cache API responses with Invoke-JiraMethod

    master

    To improve performance and reduce API load, you can cache responses using -CacheKey and -CacheExpiry. Subsequent calls with the same CacheKey will return the cached data until the expiry time is reached.

    • Use -BypassCache to force a fresh API call and update the cache.
    • -CacheExpiry accepts a [TimeSpan] object or a string in hh:mm:ss format.
    # Cache fields for 1 hour
    $parameter = @{
        URI = "/rest/api/latest/field"
        Method = "GET"
        CacheKey = "Fields"
        CacheExpiry = [TimeSpan]::FromHours(1)
    }
    Invoke-JiraMethod @parameter
    
    # Force a fresh call, ignoring cache
    Invoke-JiraMethod -URI $uri -CacheKey "Fields" -BypassCache $true
    
    # Using string literal for TimeSpan (45 minutes)
    Invoke-JiraMethod -URI $uri -CacheKey "Custom" -CacheExpiry "00:45:00"
  10. Structure of a public function test

    master

    Public function tests are organized into three distinct sections to ensure full coverage of the exported interface:

    1. Signature Tests: Verifies function parameters, types, default values, and mandatory status to ensure interface stability.
    2. Behavior Tests: Tests the core logic, including input resolution (e.g., converting strings to objects), verifying that Invoke-JiraMethod is called correctly, checking return values, and exercising all code paths.
    3. Input Validation Tests: Tests parameter sets and input handling, covering both positive cases (valid inputs) and negative cases (invalid inputs with expected error messages), as well as pipeline support and multiple item processing.
  11. Use Strongly-Typed `AtlassianPS.JiraPS.*` Classes

    master

    JiraPS v3 promotes core domain types to real .NET classes under the AtlassianPS.JiraPS namespace. This enables IntelliSense, strong typing, and identifier-based equality.

    Key Types:

    • AtlassianPS.JiraPS.Issue (Identifier: Key)
    • AtlassianPS.JiraPS.User (Identifier: AccountId on Cloud, else Name)
    • AtlassianPS.JiraPS.Project (Identifier: Key)
    • AtlassianPS.JiraPS.Filter (Identifier: ID)
    • AtlassianPS.JiraPS.Version (Identifier: ID or Name)
    • AtlassianPS.JiraPS.Group (Identifier: Name)

    Equality: Objects are compared by their canonical identifier rather than object reference. For example, two User objects with the same AccountId will be equal via -eq.

    # Idiomatic type checking
    if ($obj -is [AtlassianPS.JiraPS.Issue]) { ... }
    
    # Constructing a mock object
    $mockIssue = [AtlassianPS.JiraPS.Issue]@{ Key = 'TEST-1'; Summary = 'mock' }