Skip to content

Commit

Permalink
Restructured module with improved organization and added documentation
Browse files Browse the repository at this point in the history
- Reorganized functions into private/public folders for clarity.
- Added help documentation for functions.
- Implemented GitHub Actions for build and release workflows.
  • Loading branch information
Nillth committed Nov 19, 2024
1 parent 014d736 commit bfaa3ee
Show file tree
Hide file tree
Showing 22 changed files with 1,299 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ about: Suggest an idea for this project
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Is there and [API](https://help.qlik.com/en-US/nprinting/November2018/APIs/NP+API/index.html) that needs to be implemented? If so which one.**
**Is there and [API](https://help.qlik.com/en-US/nprinting/csh/Content/NPrinting/Extending/NPrinting-APIs-Reference-Redirect.htm) that needs to be implemented? If so which one.**

**Describe the solution you'd like**
A clear and concise description of what you want to happen.
Expand Down
65 changes: 65 additions & 0 deletions .github/workflows/BuildModule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# This is a basic workflow to help you get started with Actions

name: Module Build

# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "main" branch
push:
branches-ignore: [ 'main', '**-alpha', '**-dev' ]
paths-ignore:
- '.github/workflows/**'
- 'docs/**'
pull_request:
branches: [ "main" ]
paths-ignore:
- '.github/workflows/**'
- 'docs/**'

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build-module:
name: Build Module Manifest
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}
fetch-depth: 0
- name: Build the PowerShell Module
id: pwsh-build
shell: pwsh
env:
GH_TOKEN: ${{ secrets.API_TOKEN }}
run: |
Get-ChildItem -Recurse -Include "BuildModule.ps1"|%{. $_.FullName}
- name: Build the Readme
uses: baileyjm02/markdown-to-pdf@v1
with:
input_dir: ${{ steps.pwsh-build.outputs.ModuleDir }}
output_dir: ${{ steps.pwsh-build.outputs.ModuleDir }}
# Default is true, can set to false to only get PDF files
table_of_contents: value
build_html: true
build_pdf: true
- name: Upload test results
uses: actions/upload-artifact@v3
id: artifact
with:
name: ${{ steps.pwsh-build.outputs.ModuleName }}
path: ${{ steps.pwsh-build.outputs.ModuleDir }}
- name: Release
uses: softprops/action-gh-release@v1
if: ${{ github.ref == 'refs/heads/main' }}
with:
token: ${{ secrets.API_TOKEN }}
name: ${{ steps.pwsh-build.outputs.ModuleName }} - ${{ steps.pwsh-build.outputs.Version }}
tag_name: ${{ steps.pwsh-build.outputs.Version }}
generate_release_notes: true
draft: true
files: |
${{ steps.pwsh-build.outputs.ModuleZip }}
32 changes: 32 additions & 0 deletions .github/workflows/Release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Publish Module

on:
release:
types: [published]

workflow_dispatch:

jobs:
notification:
runs-on: ubuntu-latest
env:
REQUIRED_TOKEN: ${{ secrets.PWSHGALLERY_TOKEN != '' }}

steps:
- name: Download release asset
if: ${{ env.REQUIRED_TOKEN == 'true' }}
id: download-release-asset
uses: robinraju/[email protected]
with:
latest: true
#zipBall: true
token: ${{ secrets.API_TOKEN }}
- name: Release the PowerShell Module
if: ${{ env.REQUIRED_TOKEN == 'true' }}
id: pwsh-release
shell: pwsh
env:
PWSHGALLERY_TOKEN: ${{ secrets.PWSHGALLERY_TOKEN }}
run: |
Get-ChildItem -File -Filter "*.zip"|Expand-Archive
Get-ChildItem -File -Filter "*.psd1" -Recurse |%{Publish-Module -Path $_.Directory.FullName -NuGetApiKey $ENV:PWSHGALLERY_TOKEN}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
QlikNPrinting-CLI/*
QlikNPrinting-CLI.zip
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2020 Marc Collins
Copyright (c) 2024 Marc Collins

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
22 changes: 22 additions & 0 deletions Module_Config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"RepositoryURI": "https://github.com/QlikProfessionalServices/QlikNPrinting-CLI",
"ModuleName": "QlikNPrinting-CLI",
"ModuleManifest": {
"Author": "Marc Collins",
"CompanyName": "Qlik - Customer Success",
"Copyright": null,
"Description": "The Qlik NPrinting CLI is a PowerShell module designed to interact with and manage Qlik NPrinting environments programmatically",
"DotNetFrameworkVersion": null,
"FileList": null,
"FunctionsToExport": null,
"Guid": "eca92804-c4ca-4aa8-9313-44d71005379d",
"HelpInfoUri": null,
"LicenseUri": null,
"ModuleVersion": "1.2",
"PrivateData": null,
"ProjectUri": null,
"ReleaseNotes": null,
"Tags": null
},
"AllowDynamicContent": true
}
Binary file modified QlikNPrinting-CLI.psm1
Binary file not shown.
25 changes: 25 additions & 0 deletions src/Private/AuthenticateNPrinting.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
function AuthenticateNPrinting {
param (
[string]$AuthScheme,
[pscredential]$Credentials
)

$LoginUrl = if ($AuthScheme -eq 'NPrinting') {
"$($script:NPEnv.URLServerBase)/login"
} else {
"$($script:NPEnv.URLServerAPI)/login/$AuthScheme"
}

Write-Verbose "Authenticating to $LoginUrl"
if ($AuthScheme -eq 'NPrinting' -and $Credentials) {
$Body = @{
username = $Credentials.UserName
password = $Credentials.GetNetworkCredential().Password
} | ConvertTo-Json -Depth 3

return Invoke-NPRequest -Path $LoginUrl -method 'Post' -Data $Body
}

return Invoke-NPRequest -Path $LoginUrl -method 'Get'
}

12 changes: 12 additions & 0 deletions src/Private/DecodeUnicodeEscapes.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function DecodeUnicodeEscapes {
param (
[string]$InputString
)

$decoded = [regex]::Replace($InputString, '\\u([0-9a-fA-F]{4})', {
param($match)
[char]::ConvertFromUtf32([int]::Parse($match.Groups[1].Value, [System.Globalization.NumberStyles]::HexNumber))
})

return $decoded
}
28 changes: 28 additions & 0 deletions src/Private/GetNPFilter.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
function GetNPFilter {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, HelpMessage = "The property to filter by.")]
[string]$Property,

[Parameter(Mandatory = $true, HelpMessage = "The value to filter for.")]
[string]$Value,

[Parameter(Mandatory = $true, HelpMessage = "The existing filter string.")]
[string]$Filter
)

# Process the property and value for filtering
if ($null -ne $Property -and $null -ne $Value) {
# Replace wildcard character `*` with `%`
$Value = $Value -replace '\*', '%'

# Determine the query separator based on the current filter
$QuerySeparator = if ($Filter.StartsWith('?')) { '&' } else { '?' }

# Append the new filter clause
$Filter = "$Filter$QuerySeparator$Property=$Value"
}

# Return the updated filter string
return $Filter
}
25 changes: 25 additions & 0 deletions src/Private/GetXSRFToken.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

function GetXSRFToken {
[CmdletBinding()]
param (
[Parameter(HelpMessage = 'Return only the raw token value instead of the header dictionary.')]
[switch]$Raw
)

try {
# Retrieve the XSRF token from the cookies
$Token = $script:NPEnv.WebRequestSession.Cookies.GetCookies($script:NPEnv.URLServerBase) | Where-Object { $_.Name -eq 'NPWEBCONSOLE_XSRF-TOKEN' }

# Return the raw token value or header dictionary based on the Raw parameter
if ($Raw) {
return $Token.Value
} else {
# Create a header dictionary with the token
$Header = [System.Collections.Generic.Dictionary[String, String]]::new()
$Header.Add('X-XSRF-TOKEN', $Token.Value)
return $Header
}
} catch {
Write-Error "Failed to retrieve XSRF token: $_"
}
}
27 changes: 27 additions & 0 deletions src/Private/SetTrustAllCertificates.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

function SetTrustAllCertificates {
if (-not ('CTrustAllCerts' -as [type])) {
Add-Type -TypeDefinition @'
using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
public static class CTrustAllCerts {
public static bool ReturnTrue(object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors) { return true; }
public static RemoteCertificateValidationCallback GetDelegate() {
return new RemoteCertificateValidationCallback(CTrustAllCerts.ReturnTrue);
}
}
'@
Write-Verbose -Message 'Added Cert Ignore Type'
}

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = [CTrustAllCerts]::GetDelegate()
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Write-Verbose -Message 'Server Certificate Validation Bypass'
}
Loading

0 comments on commit bfaa3ee

Please sign in to comment.