Skip to content

Release 1.1.1 - #9

Merged
Sekers merged 23 commits into
mainfrom
develop
Sep 16, 2026
Merged

Sekers merged 23 commits into
mainfrom
develop

Conversation

@Sekers

@Sekers Sekers commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Summary

Release pull request for 1.1.1: merges develop into main. After it merges, the merge commit is tagged 1.1.1,
which runs the Release workflow. The release notes are the 1.1.1 section of CHANGELOG.md, prepared in #8.

This targets main because it is a release, not a hotfix.

Release classification

  • Major: breaks the public contract (an existing script or configuration file can stop working)
  • Minor: adds backward-compatible functionality
  • Patch: a backward-compatible fix
  • None: no user-visible change (tests, CI, or contributor documentation only)

Checklist

  • Targets develop, or main for a hotfix
  • CHANGELOG.md has an entry under [Unreleased] in the right section, or the change is not user-visible
  • .\Tests\Invoke-Tests.ps1 passes
  • Contains no real tenant names, email domains, secrets, or configuration files
  • Any live Microsoft Graph testing was done in a test tenant and is described above

Sekers added 21 commits November 7, 2025 15:37
Merge Main pulls into Develop
Moved the MgPermissionType, MgTenantID, and MgClientID assignments above the
module checks so the permission type is set when the Files check tests it.
- AGENTS.md: changelog, file encoding and line ending, safety, and code rules
  for AI assistants. CLAUDE.md points to it.
- .gitattributes: pin every text file to LF so checkouts match the repository
  regardless of core.autocrlf.
- ScriptMessage.psm1: remove the UTF-8 byte order mark; the file is pure ASCII.
- Research_Notes/: PowerShell language behavior, file encoding and line
  endings, and Microsoft Graph behavior, with every claim labelled by its
  evidence (measured, from source, from documentation, or unverified).
- AGENTS.md: rules for writing research notes, and keep links to them out of
  changelog entries.
The To, CC, and BCC check converted the raw parameters to strings. A
one-item array holding a PSCustomObject converts to an empty string, so a
valid single recipient read from a JSON config was rejected. The check now
runs on the converted recipients and requires at least one non-blank
address, which also rejects recipients whose addresses are all blank.

- Send-ScriptMessage.ps1: check the converted recipients instead of the
  raw parameters.
- Tests/Send-ScriptMessage.Tests.ps1: first Pester test (Pester 5 or
  later), covering accepted and rejected recipient shapes with Microsoft
  Graph mocked.
- CHANGELOG.md: new 1.1.1 section (Unreleased) for the fix.
- Tests.yml: lint the workflows (actionlint) and run the Pester suite under
  Windows PowerShell 5.1 and PowerShell 7 on pushes, pull requests, and when
  called by the release workflow.
- Release.yml: replaces PSGallery.yml. A pushed version tag is checked
  (annotated, matches the manifest, dated changelog section, on main or on
  develop for a prerelease), tested, built once, published to the PowerShell
  Gallery from the psgallery environment, and only then released on GitHub
  with the same package attached.
- Tests/Invoke-Tests.ps1: runs the suite in both editions and exits non-zero
  on any failure; can use a pinned Pester version saved on demand.
- Tests/ScriptMessage.Module.Tests.ps1: the manifest is valid, exports match
  the Public folder, and PSScriptAnalyzer reports no errors.
… process

- RELEASING.md: versioning rules (Semantic Versioning after 1.1.0, the public
  contract, hard cases), the Simple Modified Gitflow branch rules, the
  tag-triggered release steps, hotfixes, prereleases, and the repository
  settings that enforce them.
- CONTRIBUTING.md and .github/pull_request_template.md: everyday workflow,
  release classification, and a changelog and test checklist for pull
  requests.
- CHANGELOG.md: Keep a Changelog preamble, with the unreleased fix moved
  under [Unreleased] and Fixed.
- AGENTS.md: the changelog uses [Unreleased] and the Keep a Changelog
  categories; a release is an annotated tag handled by Release.yml; text files
  are UTF-8 without a BOM, and PowerShell files are ASCII only.
- README.md: a Versioning section replaces the public preview note, and the
  branching paragraph links CONTRIBUTING.md and RELEASING.md.
- ScriptMessage.psd1: PSEdition_Desktop, PSEdition_Core, and Windows gallery
  tags, and the license and release notes links point at main.
- Research_Notes/File-Encoding-And-Line-Endings.md: the ASCII rule covers
  PowerShell files, and how config files are read on 5.1 is unverified.
The Chat case created the message hashtable only inside its attachment branch,
so a chat with no attachments indexed into a null array when adding members and
sent nothing, reporting the error in the result. A chat sent in the same call as
mail worked only because the Mail case left the hashtable behind.

Build the message and convert the body before the attachment branch, which also
stops the mail message object from leaking into the chat.

Adds Pester coverage for one-on-one chats, group chats, and mail plus chat in a
single call. None of it contacts a tenant.
The chat attachment upload encoded the filename with
[System.Web.HttpUtility]::UrlEncode. Windows PowerShell 5.1 does not always
have that type loaded, so a chat with an attachment could fail and send
nothing. Form encoding also turned each space into a plus sign, which a URL
path reads literally. Use [uri]::EscapeDataString, which needs no extra
assembly in either edition and encodes a space as %20.

- MicrosoftGraph.ps1: escape the upload filename with EscapeDataString.
- Tests/Send-ScriptMessage.Tests.ps1: a one-on-one chat with an attachment
  checks the upload path, and mail with one and two attachments checks that
  every attachment reaches Send-MgUserMail. None of it contacts a tenant.
- CHANGELOG.md: two Fixed entries, one for the 5.1 failure and one for
  spaces in filenames.
- Research_Notes/PowerShell-Language-Behavior.md: the measured 5.1 failure
  and why it can look intermittent.
… chat-only setups

Connect-ScriptMessage checked for Microsoft.Graph.Users.Actions on every
Microsoft Graph connection, repeating the per-message-type module checks in
Connect-ScriptMessage_MicrosoftGraph, so a configuration that allows only Chat
failed without that module. The check never shipped in a release. Remove it,
and add tests for a chat-only configuration and a configuration that allows
Mail.
With application permissions, Send-ScriptMessage connects to Microsoft Graph
before every send, replacing any connection the calling script made itself.
Disconnecting afterwards leaves that script with no connection, so its next
Graph command fails with "Authentication needed". Staying connected does not
restore the script's own connection, but a script that uses the same app keeps
working. The template switched this default to true after 1.1.0, so false
matches the last release and needs no changelog entry.

- Templates/config_scriptmessage.json: MgDisconnectWhenDone is false.
- Research_Notes/Microsoft-Graph-Behavior.md: section 7 records how
  application-permission connections behave, measured in both editions
  without sending a message. Section 6 now limits its token cache inference
  to delegated permissions and cites the SDK 2.25.0 source.
Add the user-visible changes since 1.1.0 that had no entry, each checked
against the 1.1.0 tag: Microsoft.Graph.Files no longer being required with
application permissions, the certificate password error naming Microsoft
Graph, and the template's new
MgDelegatedPermission_RequestFilesReadWritePermission setting. Remove the
introduction about format and versioning, which RELEASING.md covers.
…aths

Get-ScriptMessageConfig read the file with Get-Content and no -Encoding, so
non-ASCII characters were silently misread. Windows PowerShell 5.1 decoded a
UTF-8 file without a byte order mark in the legacy code page, and PowerShell 7
decoded a legacy code page file as UTF-8. Get-Content -Path also treated square
brackets as wildcard characters, so a path containing them was never found.

The file is now opened with .NET after PowerShell resolves the path literally.
A byte order mark sets the encoding; without one, the file is read as strict
UTF-8, falling back to Encoding.GetEncoding(0) when it is not valid UTF-8.
That code page is the system's in both editions, the same one 5.1's
Get-Content uses. -Encoding UTF8 alone would have broken 5.1 reads of files
written by 5.1's Set-Content. A wildcard in the path no longer matches, which
was never a supported use.

- Tests/Get-ScriptMessageConfig.Tests.ps1: four encodings, a relative path, a
  PowerShell drive, brackets, and a missing file. Each encoding and bracket
  test fails against the previous reader in the edition its bug affected.
- Research_Notes/File-Encoding-And-Line-Endings.md section 5 and
  Research_Notes/PowerShell-Language-Behavior.md section 8 record the
  measurements.
- CHANGELOG.md: three Minor entries under Fixed.
Research_Notes/PowerShell-Language-Behavior.md section 9, measured in both
editions: a lone PSCustomObject converts to @{Name=A; ...}, but one inside a
one-item array converts to an empty string, so [string]::IsNullOrEmpty reports
true. The recipient conversion functions pair that test with a second one,
which is what keeps a single recipient from being treated as none. A single
PSCustomObject passed to Send-ScriptMessage -Attachment, which is not a
supported type, comes back as no attachment instead of raising an error.
- ScriptMessage.psd1: ModuleVersion 1.1.1.
- CHANGELOG.md: the Unreleased entries become the dated 1.1.1 section, under
  a new empty Unreleased section.
Copilot AI lite review requested due to automatic review settings September 16, 2026 19:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The release automation would not reliably run/publish due to broken tag filters and invalid artifact action versions, and there’s also a confirmed runtime-breaking bug in the certificate-file authentication path.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Release PR to ship ScriptMessage 1.1.1 by merging develop into main, including the release notes and the accompanying reliability improvements (tests/CI), documentation, and Microsoft Graph behavior fixes.

Changes:

  • Adds a Pester test suite (plus a cross-edition runner) and GitHub Actions workflows to run tests and publish releases.
  • Fixes Microsoft Graph sending edge cases (recipient validation, chat messages with/without attachments, attachment filename escaping, config file path/encoding handling).
  • Updates release/process documentation and supporting repo metadata (manifest version/tags/links, changelog, contributing and releasing docs, .gitattributes).
File summaries
File Description
Tests/Send-ScriptMessage.Tests.ps1 Adds coverage for recipient validation, chat sends (with/without attachments), and mail attachments.
Tests/ScriptMessage.Module.Tests.ps1 Validates manifest and exported functions; runs PSScriptAnalyzer errors check when available.
Tests/Invoke-Tests.ps1 Adds a runner to execute tests under both Windows PowerShell 5.1 and PowerShell 7 (optionally with pinned Pester).
Tests/Get-ScriptMessageConfig.Tests.ps1 Adds tests for config decoding across BOM/UTF-8/UTF-16/legacy code page and path edge cases.
Tests/Connect-ScriptMessage.Tests.ps1 Adds tests for Graph sub-module requirements depending on allowed message types.
Templates/config_scriptmessage.json Updates sample config with additional settings (e.g., mail/chat and delegated files permission).
ScriptMessage/Services/MicrosoftGraph.ps1 Adjusts Graph module checks and chat attachment upload filename escaping; refactors chat body construction.
ScriptMessage/ScriptMessage.psm1 Removes BOM / normalizes header line.
ScriptMessage/ScriptMessage.psd1 Bumps module version to 1.1.1 and updates metadata links/tags.
ScriptMessage/Public/Send-ScriptMessage.ps1 Fixes recipient validation to reject only truly blank addresses (and not reject 1-item recipient arrays).
ScriptMessage/Public/Get-ScriptMessageConfig.ps1 Switches to a BOM-aware + fallback decoding strategy and resolves PS paths to full filesystem paths.
ScriptMessage/Public/Connect-ScriptMessage.ps1 Clarifies service-level module checks responsibility in comment.
Research_Notes/PowerShell-Language-Behavior.md Adds measured PowerShell runtime behaviors that affect module implementation choices.
Research_Notes/Microsoft-Graph-Behavior.md Documents Graph/SDK behavior and constraints the module relies on (with evidence labeling).
Research_Notes/File-Encoding-And-Line-Endings.md Adds measured evidence behind encoding/line-ending rules and config-reading behavior.
RELEASING.md Introduces formal versioning/branching/release workflow documentation.
README.md Updates top-level docs to reflect semver/versioning and contribution/release guidance links.
CONTRIBUTING.md Adds contributor workflow guidance and safety/testing rules.
CLAUDE.md Adds pointer to AGENTS.md as the shared AI guidance source.
CHANGELOG.md Adds the 1.1.1 dated release section and reintroduces an empty [Unreleased] section.
AGENTS.md Adds the consolidated contributor/AI guidance, including changelog and encoding rules.
.github/workflows/Tests.yml Adds CI workflow for lint + Pester (cross-edition).
.github/workflows/Release.yml Adds tag-driven release workflow: validate → test → publish to PSGallery → create GitHub release.
.github/workflows/PSGallery.yml Removes legacy PSGallery publish workflow (superseded by Release.yml).
.github/pull_request_template.md Adds structured PR template with release classification and checklist.
.gitattributes Pins LF line endings across text files and marks binaries explicitly.
Review details
  • Files reviewed: 26/26 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/Release.yml
Comment thread ScriptMessage/Services/MicrosoftGraph.ps1
[Unreleased] now exists only on develop, and only while it has entries. The
release-prep pull request renames it to the version heading without adding a
new empty one, and the first later pull request with a changelog entry adds
it back. The Release workflow's tag check refuses to publish a CHANGELOG.md
that still has an [Unreleased] section.

- Release.yml: the validate job fails on an [Unreleased] heading.
- RELEASING.md, AGENTS.md, CONTRIBUTING.md, pull request template: add the
  section only with an entry, never during release prep, and merge nothing
  else into develop between release prep and the release merge.
- CHANGELOG.md: remove the empty [Unreleased] section added by the 1.1.1
  release prep.
Keep the [Unreleased] changelog section off main
@Sekers
Sekers merged commit 7e0b665 into main Sep 16, 2026
4 checks passed
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.

2 participants