Skip to content

Latest commit

 

History

96 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

ObjoPublisher

ObjoPublisher is a collection of reusable GitHub Actions workflows for publishing applications created with Objo Studio.

The repository centralizes all publishing logic so that individual application repositories only need small wrapper workflows that provide project-specific parameters and secrets.

Using reusable workflows has several advantages:

  • Publishing logic is maintained in one place.
  • Improvements automatically benefit every project.
  • Build workflows remain small and easy to understand.
  • Publishing behavior is consistent across all projects.
  • Objo Studio installation and caching are handled automatically.
  • License activation and cleanup are handled automatically.

Available reusable workflows

Workflow Description
publish_objo_macos.yml Publishes macOS applications, optionally signs and notarizes them using Apple Developer certificates.
publish_objo_linux.yml Publishes Linux applications for one or more runtime targets.
publish_objo_windows.yml Publishes Windows applications and signs generated MSIX packages using the official Azure Trusted Signing GitHub Action.
publish_objo_windows_objosign.yml Publishes Windows applications and lets Objo Studio perform Azure Trusted Signing during publishing.

General features

All reusable workflows share the same design principles.

Optional SFTP upload

The macOS, Linux, and Windows publishing workflows can optionally upload generated artifacts to an SFTP server after the normal GitHub artifact upload succeeds.

SFTP upload is enabled only when all four values are supplied:

  • sftp-url
  • sftp-username
  • sftp-password
  • sftp-host-fingerprint

If any of them is missing or empty, SFTP upload is skipped and publishing continues normally.

Before any file is uploaded, the workflow verifies that the SSH host key presented by the SFTP server matches the expected fingerprint supplied through the sftp-host-fingerprint secret. This protects against connecting to an unexpected or malicious server and avoids the "trust on first use" approach commonly used with SSH. On Windows only RSA SHA256 is accepted, version of curl in Windows runners doesn't support ECDSA or ED25519. If you want higher security on Linux or macOS you can create two repository secrets: one for Windows holding SHA256 RSA key format, the other holding SHA256 ED25519 or ECDSA key formats, then you pass first one to Windows publishing workflow, second one to Linux and/or macOS.

Only after the host key has been successfully verified is the server added to the runner's known_hosts file and the upload allowed to continue.

The workflows upload files into a platform-specific subdirectory below sftp-url:

Platform Destination
macOS <sftp-url>/macos/
Linux <sftp-url>/linux/
Windows <sftp-url>/windows/

The fail-on-sftp-error boolean input controls what happens when the application build succeeds but SFTP upload fails.

Build SFTP upload fail-on-sftp-error Result
success success either exit code 0
failure not attempted either exit code 1
success failed true exit code 2
success failed false exit code 0
success skipped either exit code 0

Each reusable workflow exposes an sftp-upload workflow output with one of these values:

  • success
  • failed
  • skipped

The workflows also write a summary to the GitHub Actions workflow summary showing the build and SFTP results.


Automatic Objo Studio installation

If the requested version of Objo Studio is already cached on the GitHub runner, it is restored immediately.

Otherwise the workflow automatically downloads the requested version from the official Objo download site and stores it in the GitHub Actions cache for future workflow runs.

By default the latest released version of Objo Studio is used.


Automatic license management

The workflows select the licensing scheme from the resolved Objo Studio version:

  • Versions earlier than 26.8.4 use persistent activation. The workflow creates a temporary key file, activates the license, publishes, deactivates the license even if publishing fails, and removes the key file.
  • Version 26.8.4 and later use temporary activation by passing --license-key-env OBJO_LICENSE_KEY to objo publish. No persistent activation or deactivation is performed.

Output directories

Instead of publishing into fixed platform-specific folders, every workflow publishes into a directory under the current runner user's home directory.

Default locations are:

Platform Default output directory
macOS $HOME/Documents/Publish
Linux $HOME/Publish
Windows %USERPROFILE%\Publish

The output directory can be changed using the output-directory workflow input.


Multiple publish targets

The macOS, Linux and Windows reusable workflows support publishing multiple runtime identifiers in a single execution.

Example:

with:
  targets: "osx-arm64, osx-x64"
with:
  targets: "linux-x64, linux-arm64"
with:
  targets: "win-x64, win-arm64"

Whitespace around target names is ignored automatically.


Selecting the Objo Studio version

By default every reusable workflow automatically determines the latest released version of Objo Studio.

A specific version can be requested:

with:
  objo-version: "26.7.1"

Repository structure

.github/
└── workflows/
    publish_objo_linux.yml
    publish_objo_macos.yml
    publish_objo_windows.yml
    publish_objo_windows_objosign.yml

Each workflow can be called from another repository using:

jobs:
  publish:
    uses: madamov/ObjoPublisher/.github/workflows/<workflow>.yml@v1

Files created by an earlier job must be transferred through a workflow artifact because reusable workflows run on a separate runner. For example:

jobs:
  prepare-resources:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - name: Generate release notes
        run: ./scripts/generate-release-notes.sh
      - uses: actions/upload-artifact@v7
        with:
          name: release-resources
          path: RELEASE_NOTES.md

  publish:
    needs: prepare-resources
    uses: madamov/ObjoPublisher/.github/workflows/<workflow>.yml@v1
    with:
      solution-file: MyGreatApp.objosln
      project-file: Projects/MyGreatApp/project.json
      resource-artifact-name: release-resources

Use resource-files for files committed to the application repository and resource-artifact-name for generated files. Artifact files are copied into the project's Resources/Files directory by basename; existing files with the same names are overwritten.


Workflow documentation

The following sections describe each reusable workflow in detail.

publish_objo_macos.yml

Publishes one or more macOS application bundles created with Objo Studio.

Depending on the available secrets, the workflow can produce either:

  • unsigned DMG packages, or
  • fully signed and notarized DMG packages ready for distribution.

Apple code signing is optional. If the Apple signing secrets are not supplied, the workflow automatically skips all signing and notarization steps and produces unsigned DMG files.

Generated DMG files can also be uploaded to an SFTP server when SFTP parameters are supplied.


Publishing process

Checkout repository
        │
        ▼
Validate inputs
        │
        ▼
Determine Objo Studio version
        │
        ▼
Restore or download Objo Studio
        │
        ▼
(Optional)
Install Apple signing certificate
        │
        ▼
(Optional)
Create notarization profile
        │
        ▼
(Optional)
Update project.json
        │
        ▼
Activate Objo Studio license
        │
        ▼
Publish application
        │
        ▼
Collect DMG files
        │
        ▼
Upload GitHub artifact
        │
        ▼
(Optional)
Upload DMG files to SFTP
        │
        ▼
Deactivate license
        │
        ▼
Write workflow summary

Workflow inputs

Input Required Default Description
solution-file ✔ Path to the Objo solution file.
project-file ✔ Path to project.json.
resource-files empty Newline-separated file paths copied into the project's Resources/Files directory before publishing.
resource-artifact-name empty Artifact containing files generated by an earlier job. Its files are copied into the project's Resources/Files directory.
application-name ✔ Application name used when collecting artifacts.
app-version empty Semantic application version. Valid values update MajorVersion, MinorVersion, and PatchVersion; empty or invalid values leave them unchanged.
output-directory Publish Output directory under $HOME/Documents.
targets osx-arm64,osx-x64 Comma-separated list of runtime identifiers.
artifact-name objo-macos-publish Uploaded artifact name.
apple-notary-profile objo-notarization Name of the temporary notarytool profile.
objo-version latest Specific Objo Studio version to use.
sftp-url empty Base SFTP URL. SFTP upload is skipped when this or either SFTP credential is missing.
fail-on-sftp-error false Exit with code 2 when build succeeds but SFTP upload fails.

Workflow secrets

Required

Secret Description
objo-license Objo Studio license key.

Optional Apple signing secrets

If every Apple signing secret below is supplied, the application is signed and notarized.

If one or more are omitted, publishing continues without signing.

Secret Description
apple-certificate Base64 encoded Apple Developer certificate (.p12).
apple-certificate-name Signing identity name.
apple-certificate-password Password protecting the .p12 file.
apple-team-id Apple Developer Team ID.
apple-id Apple Developer account email address.
apple-app-specific-password App-specific password used by notarytool.

Optional SFTP secrets

Secret Description
sftp-username Username used to authenticate to the SFTP server.
sftp-password Password used to authenticate to the SFTP server.
sftp-host-fingerprint Expected SHA256 (RSA, ECDSA and ED25519 are all supported) fingerprint of the SFTP server’s SSH host key. The workflow verifies the server’s identity before uploading any files.

Both credentials, sftp-host-fingerprint and sftp-url must be supplied for SFTP upload to run.


Runtime identifiers

Supported runtime identifiers are those supported by Objo Studio.

Typical examples are:

Runtime identifier Platform
osx-arm64 Apple Silicon
osx-x64 Intel Macs

Example:

with:
  targets: "osx-arm64"

or

with:
  targets: "osx-arm64, osx-x64"

Output directory

The default output directory is

$HOME/Documents/Publish

It can be overridden:

with:
  output-directory: Documents/MyApplication

which becomes

$HOME/Documents/MyApplication

Absolute paths are also supported.


Generated artifacts

The workflow automatically collects every generated DMG.

Typical uploaded artifacts are:

MyApplication-macOS-Apple-Silicon.dmg
MyApplication-macOS-Intel.dmg

Only artifacts that actually exist are uploaded.

For example, when publishing only

targets: osx-arm64

only the Apple Silicon DMG is uploaded.

When SFTP is configured, the same collected DMG files are uploaded to:

<sftp-url>/macos/

SFTP workflow output

The reusable workflow exposes:

${{ needs.publish.outputs.sftp-upload }}

when called from a job named publish.

Possible values are:

success
failed
skipped

Example

jobs:
  publish:
    uses: madamov/ObjoPublisher/.github/workflows/publish_objo_macos.yml@v1

    with:
      solution-file: MyGreatApp.objosln
      project-file: Projects/MyGreatApp/project.json
      resource-artifact-name: release-resources
      application-name: MyGreatApp
      output-directory: Publish
      targets: "osx-arm64, osx-x64"
      artifact-name: mygreatapp-macos

      # Optional
      # objo-version: "26.7.1"

      # Optional SFTP upload
      sftp-url: ${{ vars.SFTP_SERVER_URL }}
      fail-on-sftp-error: true

    secrets:
      objo-license: ${{ secrets.OBJO_LICENSE }}

      # Optional Apple signing
      apple-certificate: ${{ secrets.APPLE_CERTIFICATE }}
      apple-certificate-name: ${{ secrets.APPLE_CERTIFICATE_NAME }}
      apple-certificate-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
      apple-team-id: ${{ secrets.APPLE_TEAM_ID }}
      apple-id: ${{ secrets.APPLE_ID }}
      apple-app-specific-password: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}

      # Optional SFTP upload
      sftp-username: ${{ secrets.BINARIES_USER }}
      sftp-password: ${{ secrets.BINARIES_PASSWORD }}
      sftp-host-fingerprint: ${{ secrets.SFTP_HOST_FINGERPRINT }}

Notes

  • The workflow automatically creates and removes a temporary keychain.
  • The temporary notarization profile exists only for the duration of the workflow.
  • Persistent Objo Studio licenses used with versions earlier than 26.8.4 are deactivated before the workflow finishes.
  • The downloaded Objo Studio installation is cached by version.
  • If Apple signing is disabled, the workflow still produces valid unsigned DMG files.
  • SFTP upload is skipped unless sftp-url, sftp-username, and sftp-password are all supplied.
  • SFTP artifacts are uploaded under <sftp-url>/macos/.
  • The workflow writes a GitHub Actions summary and exposes the sftp-upload output.

publish_objo_linux.yml

Publishes one or more Linux applications created with Objo Studio.

The workflow restores or downloads the requested Objo Studio version, selects the compatible licensing scheme, publishes the application for one or more Linux runtime identifiers, collects the generated archives, uploads them as workflow artifacts, and optionally uploads them to SFTP.

Unlike the macOS and Windows workflows, Linux publishing does not require any platform-specific signing.


Publishing process

Checkout repository
        │
        ▼
Validate inputs
        │
        ▼
Determine Objo Studio version
        │
        ▼
Restore or download Objo Studio
        │
        ▼
Activate Objo Studio license
        │
        ▼
Publish application
        │
        ▼
Collect Linux archives
        │
        ▼
Upload GitHub artifact
        │
        ▼
(Optional)
Upload Linux archives to SFTP
        │
        ▼
Deactivate license
        │
        ▼
Write workflow summary

Workflow inputs

Input Required Default Description
solution-file ✔ Path to the Objo solution file.
project-file ✔ Path to project.json.
resource-files empty Newline-separated file paths copied into the project's Resources/Files directory before publishing.
resource-artifact-name empty Artifact containing files generated by an earlier job. Its files are copied into the project's Resources/Files directory.
application-name ✔ Application name used when naming uploaded artifacts.
app-version empty Semantic application version. Valid values update MajorVersion, MinorVersion, and PatchVersion; empty or invalid values leave them unchanged.
output-directory Publish Output directory under the current user's home directory.
targets linux-x64 Comma-separated list of Linux runtime identifiers.
artifact-name objo-linux-publish Uploaded artifact name.
objo-version latest Specific Objo Studio version to use.
sftp-url empty Base SFTP URL. SFTP upload is skipped when this or either SFTP credential is missing.
fail-on-sftp-error false Exit with code 2 when build succeeds but SFTP upload fails.

Workflow secrets

Secret Required Description
objo-license ✔ Objo Studio license key used during publishing.
sftp-username Optional SFTP username.
sftp-password Optional SFTP password.
sftp-host-fingerprint Expected SHA256 (RSA, ECDSA and ED25519 are all supported) fingerprint of the SFTP server’s SSH host key. The workflow verifies the server’s identity before uploading any files.

Both credentials, sftp-host-fingerprint and sftp-url must be supplied for SFTP upload to run.


Runtime identifiers

The workflow supports any Linux runtime identifier supported by Objo Studio.

Typical examples include:

Runtime identifier Platform
linux-x64 64-bit Intel/AMD Linux
linux-arm64 ARM64 Linux

Examples:

with:
  targets: "linux-x64"

or

with:
  targets: "linux-x64, linux-arm64"

Whitespace surrounding runtime identifiers is ignored automatically.


Output directory

The default output directory is

$HOME/Publish

It can be overridden:

with:
  output-directory: Applications/MyGreatApp

which becomes

$HOME/Applications/MyGreatApp

Absolute paths are also supported.


Generated artifacts

The workflow searches the publish directory recursively and automatically uploads every archive produced by Objo Studio.

Supported archive formats include:

  • .tar.gz
  • .tgz
  • .zip

Artifacts are renamed to include the application name and runtime identifier when appropriate.

Typical uploaded artifacts might look like:

MyGreatApp-linux-x64.tar.gz
MyGreatApp-linux-arm64.tar.gz

When SFTP is configured, the collected artifacts are also uploaded to:

<sftp-url>/linux/

SFTP workflow output

The reusable workflow exposes the sftp-upload output.

Possible values are:

success
failed
skipped

A calling workflow can read it using:

${{ needs.publish.outputs.sftp-upload }}

when the reusable workflow job is named publish.


Example

jobs:
  publish:
    uses: madamov/ObjoPublisher/.github/workflows/publish_objo_linux.yml@v1

    with:
      solution-file: MyGreatApp.objosln
      project-file: Projects/MyGreatApp/project.json
      resource-artifact-name: release-resources
      application-name: MyGreatApp
      output-directory: Publish
      targets: "linux-x64"
      artifact-name: mygreatapp-linux

      # Optional
      # objo-version: "26.7.1"

      # Optional SFTP upload
      sftp-url: ${{ vars.SFTP_SERVER_URL }}
      fail-on-sftp-error: true

    secrets:
      objo-license: ${{ secrets.OBJO_LICENSE }}

      # Optional SFTP upload
      sftp-username: ${{ secrets.BINARIES_USER }}
      sftp-password: ${{ secrets.BINARIES_PASSWORD }}
      sftp-host-fingerprint: ${{ secrets.SFTP_HOST_FINGERPRINT }}

Notes

  • Linux publishing does not require platform-specific certificates.
  • Multiple runtime identifiers can be published during a single workflow run.
  • The latest Objo Studio release is used automatically unless a specific version is requested.
  • The downloaded Objo Studio installation is cached by version.
  • Persistent Objo Studio licenses used with versions earlier than 26.8.4 are deactivated even if publishing fails.
  • Every generated Linux archive is collected and uploaded automatically.
  • SFTP upload is skipped unless all three SFTP values are supplied.
  • SFTP artifacts are uploaded under <sftp-url>/linux/.
  • The workflow writes a GitHub Actions summary and exposes the sftp-upload output.

publish_objo_windows.yml

Publishes one or more Windows applications created with Objo Studio and signs the generated MSIX packages using the official Azure Trusted Signing GitHub Action:

azure/trusted-signing-action@v2

In this workflow, Objo Studio is responsible only for generating the MSIX packages. The Azure signing fields in project.json are cleared so that Objo does not attempt to invoke signtool.exe itself.

After publishing finishes, the reusable workflow signs all generated MSIX files using the Azure Trusted Signing action.

Generated MSIX files can optionally be uploaded to an SFTP server.


Publishing process

Checkout repository
        │
        ▼
Validate inputs
        │
        ▼
Determine Objo Studio version
        │
        ▼
Restore or download Objo Studio
        │
        ▼
Configure project.json for external signing
        │
        ▼
Activate Objo Studio license
        │
        ▼
Publish unsigned MSIX packages
        │
        ▼
Deactivate Objo Studio license
        │
        ▼
Sign MSIX packages using
azure/trusted-signing-action
        │
        ▼
Collect signed MSIX packages
        │
        ▼
Upload GitHub artifact
        │
        ▼
(Optional)
Upload MSIX packages to SFTP
        │
        ▼
Write workflow summary

Workflow inputs

Input Required Default Description
solution-file ✔ Path to the Objo solution file.
project-file ✔ Path to project.json.
resource-files empty Newline-separated file paths copied into the project's Resources/Files directory before publishing.
resource-artifact-name empty Artifact containing files generated by an earlier job. Its files are copied into the project's Resources/Files directory.
application-name ✔ Application name used when collecting artifacts and generating the default correlation ID.
app-version empty Semantic application version. Valid values update MajorVersion, MinorVersion, and PatchVersion; empty or invalid values leave them unchanged.
output-directory Publish Output directory under the current Windows user's home directory.
targets win-x64 Comma-separated list of Windows runtime identifiers.
windows-format MSIX Windows output format: MSIX, folder, or zip. With Azure signing, zip is published as a folder, signed, and then zipped. Folder output is also zipped after signing for artifact and SFTP upload.
artifact-name objo-windows-publish Uploaded artifact name.
objo-version latest Specific Objo Studio version to use.
azure-correlation-id generated Optional Azure signing correlation ID. When omitted, a value based on the application name and GitHub run ID is generated.
sftp-url empty Base SFTP URL. SFTP upload is skipped when this or either SFTP credential is missing.
fail-on-sftp-error false Exit with code 2 when build succeeds but SFTP upload fails.

Workflow secrets

Secret Required Description
objo-license ✔ Objo Studio license key used during publishing.
azure-tenant-id ✔ Microsoft Entra tenant ID used by the Azure Trusted Signing action.
azure-client-id ✔ Application or service-principal client ID used to authenticate to Azure.
azure-client-secret ✔ Client secret associated with the Azure application registration.
azure-endpoint ✔ Azure Trusted Signing endpoint, for example https://wus2.codesigning.azure.net/.
azure-account-name ✔ Azure Trusted Signing account name.
azure-certificate-profile-name ✔ Trusted Signing certificate profile name.
azure-package-publisher ✔ Publisher value written into the MSIX manifest. It must match the publisher identity used by the signing certificate profile.
azure-timestamp-url Optional RFC 3161 timestamp server URL. When omitted, the signing action runs without timestamping.
sftp-username Optional SFTP username.
sftp-password Optional SFTP password.
sftp-host-fingerprint Expected SHA256 (** ONLY RSA IS SUPPORTED UNDER WINDOWS**) fingerprint of the SFTP server’s SSH host key. The workflow verifies the server’s identity before uploading any files.

Both credentials, sftp-host-fingerprint and sftp-url must be supplied for SFTP upload to run.


External signing configuration

Before publishing, the workflow modifies the Windows signing section in project.json.

The Azure signing fields used by Objo are cleared:

{
  "AzureEndpoint": "",
  "AzureAccountName": "",
  "AzureCertificateProfileName": "",
  "AzureCorrelationId": "",
  "TimestampUrl": ""
}

Only the package publisher remains populated:

{
  "PackagePublisher": "CN=..."
}

This prevents Objo from attempting to sign the package locally with signtool.exe and Azure.CodeSigning.Dlib.dll.

The generated MSIX is then signed by:

uses: azure/trusted-signing-action@v0

Runtime identifiers

The workflow supports any Windows runtime identifier supported by Objo Studio.

Typical examples include:

Runtime identifier Platform
win-x64 64-bit Intel/AMD Windows
win-arm64 ARM64 Windows
win-x86 32-bit Windows

Examples:

with:
  targets: "win-x64"

or

with:
  targets: "win-x64, win-arm64"

Whitespace around targets is removed automatically.


Output directory

The default output directory is:

%USERPROFILE%\Publish

On a GitHub-hosted Windows runner, this is typically similar to:

C:\Users\runneradmin\Publish

It can be changed:

with:
  output-directory: Documents\ObjoPublisher

which becomes:

%USERPROFILE%\Documents\ObjoPublisher

Absolute Windows paths are also supported.


Correlation ID

The correlation ID input is optional.

A caller can provide one explicitly:

with:
  azure-correlation-id: "MyGreatApp-release-42"

When omitted, the workflow generates a value similar to:

MyGreatApp-1234567890

where the numeric part is the GitHub Actions run ID.

The correlation ID is useful when reviewing Azure signing diagnostics and correlating a signing request with a specific GitHub Actions run.


Timestamping

When azure-timestamp-url is provided, the workflow uses the timestamp-enabled signing step.

When the secret is empty or omitted, the workflow uses a second signing step that does not pass timestamp parameters to the Azure action.

This avoids supplying an empty timestamp-rfc3161 value.


Generated artifacts

The workflow searches the output directory recursively for .msix packages after signing.

The packages are copied into:

%OUTPUT_DIRECTORY%\artifacts

and uploaded using actions/upload-artifact.

Typical uploaded packages might include:

com.objo.app.mygreatapp_1.1.0.0_x64.msix
com.objo.app.mygreatapp_1.1.0.0_arm64.msix

If multiple packages have the same filename, the workflow adds information from the parent directory to prevent overwriting.

When SFTP is configured, the collected packages are also uploaded to:

<sftp-url>/windows/

The workflow prefers an SFTP-capable curl.exe installed with Git for Windows and verifies SFTP support before upload.


SFTP workflow output

The reusable workflow exposes the sftp-upload output.

Possible values are:

success
failed
skipped

A calling workflow can read it using:

${{ needs.publish-windows.outputs.sftp-upload }}

when the reusable workflow job is named publish-windows.


Example

name: ObjoPublisher for Windows

on:
  workflow_dispatch:

jobs:
  publish-windows:
    uses: madamov/ObjoPublisher/.github/workflows/publish_objo_windows.yml@v1

    with:
      solution-file: MyGreatApp.objosln
      project-file: Projects/MyGreatApp/project.json
      resource-artifact-name: release-resources
      application-name: MyGreatApp
      output-directory: Publish
      targets: "win-x64"
      artifact-name: mygreatapp-windows

      # Optional
      # objo-version: "26.7.1"
      # azure-correlation-id: "MyGreatApp-${{ github.run_id }}"

      # Optional SFTP upload
      sftp-url: ${{ vars.SFTP_SERVER_URL }}
      fail-on-sftp-error: true

    secrets:
      objo-license: ${{ secrets.OBJO_LICENSE }}

      azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
      azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
      azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}

      azure-endpoint: ${{ secrets.AZURE_ENDPOINT }}
      azure-account-name: ${{ secrets.AZURE_ACCOUNTNAME }}
      azure-certificate-profile-name: ${{ secrets.AZURE_CERTIFICATEPROFILENAME }}
      azure-package-publisher: ${{ secrets.AZURE_PACKAGEPUBLISHER }}

      # Optional
      azure-timestamp-url: ${{ secrets.AZURE_TIMESTAMPURL }}

      # Optional SFTP upload
      sftp-username: ${{ secrets.BINARIES_USER }}
      sftp-password: ${{ secrets.BINARIES_PASSWORD }}
      sftp-host-fingerprint: ${{ secrets.SFTP_HOST_FINGERPRINT }}

Notes

  • Objo Studio does not perform Windows signing in this workflow.
  • Azure signing metadata is deliberately cleared from project.json.
  • The package publisher is still written into the project because the MSIX manifest must contain the correct publisher identity.
  • The official Azure Trusted Signing GitHub Action signs all generated MSIX packages recursively.
  • Persistent Objo Studio licenses used with versions earlier than 26.8.4 are deactivated immediately after publishing.
  • Multiple Windows targets are supported in one run.
  • Objo Studio is cached by version.
  • Timestamping is optional.
  • SFTP upload is skipped unless all three SFTP values are supplied.
  • SFTP artifacts are uploaded under <sftp-url>/windows/.
  • The workflow writes a GitHub Actions summary and exposes the sftp-upload output.

publish_objo_windows_objosign.yml

Publishes one or more Windows applications created with Objo Studio and lets Objo Studio perform Azure Trusted Signing during the publish operation.

Unlike publish_objo_windows.yml, this workflow does not use the official Azure Trusted Signing GitHub Action.

Instead, it:

  • installs the Microsoft Azure Artifact Signing Client Tools,
  • locates Azure.CodeSigning.Dlib.dll,
  • configures the Windows signing section in project.json,
  • lets Objo invoke signtool.exe,
  • and produces already signed MSIX packages.

This workflow is useful when you prefer Objo Studio to manage both publishing and signing.


Publishing process

Checkout repository
        │
        ▼
Validate inputs
        │
        ▼
Determine Objo Studio version
        │
        ▼
Restore or download Objo Studio
        │
        ▼
Install Azure Artifact Signing Client Tools
        │
        ▼
Locate Azure.CodeSigning.Dlib.dll
        │
        ▼
Configure Windows signing in project.json
        │
        ▼
Activate Objo Studio license
        │
        ▼
Publish and sign application
        │
        ▼
Deactivate license
        │
        ▼
Collect signed MSIX packages
        │
        ▼
Upload artifacts

Workflow inputs

Input Required Default Description
solution-file ✔ Path to the Objo solution file.
project-file ✔ Path to project.json.
resource-files empty Newline-separated file paths copied into the project's Resources/Files directory before publishing.
resource-artifact-name empty Artifact containing files generated by an earlier job. Its files are copied into the project's Resources/Files directory.
application-name ✔ Application name used when generating the default Azure correlation ID and naming artifacts.
app-version empty Semantic application version. Valid values update MajorVersion, MinorVersion, and PatchVersion; empty or invalid values leave them unchanged.
output-directory Publish Output directory under the current Windows user's home directory.
targets win-x64 Comma-separated list of Windows runtime identifiers.
windows-format MSIX Windows output format: MSIX, folder, or zip. With Azure signing, zip is published as a folder, signed, and then zipped. Folder output is also zipped after signing for artifact and SFTP upload.
artifact-name objo-windows-signed-publish Uploaded artifact name.
objo-version latest Specific Objo Studio version to use.
azure-correlation-id generated Optional Azure correlation ID. When omitted, the workflow generates one automatically.

Workflow secrets

Secret Required Description
objo-license ✔ Objo Studio license key.
azure-endpoint ✔ Azure Trusted Signing endpoint, for example https://wus2.codesigning.azure.net/.
azure-account-name ✔ Azure Trusted Signing account name.
azure-certificate-profile-name ✔ Azure Trusted Signing certificate profile name.
azure-package-publisher ✔ Publisher value written into the MSIX manifest. It must match the publisher configured in the Azure certificate profile.
azure-timestamp-url Optional RFC 3161 timestamp server URL. When omitted, Objo signs without timestamping.
sftp-username Optional SFTP username.
sftp-password Optional SFTP password.
sftp-host-fingerprint Expected SHA256 (** ONLY RSA IS SUPPORTED UNDER WINDOWS**) fingerprint of the SFTP server’s SSH host key. The workflow verifies the server’s identity before uploading any files.

Both credentials, sftp-host-fingerprint and sftp-url must be supplied for SFTP upload to run.


Azure authentication

This workflow does not require Azure authentication credentials such as:

  • Azure Tenant ID
  • Azure Client ID
  • Azure Client Secret

Objo Studio performs Azure Trusted Signing using Microsoft's Azure Artifact Signing Client Tools and the authentication mechanisms supported by those tools on the runner.


Azure Artifact Signing Client Tools

Before publishing begins, the workflow installs Microsoft's Azure Artifact Signing Client Tools using winget.

After installation, it automatically searches several known installation locations to locate:

Azure.CodeSigning.Dlib.dll

The discovered DLL path is exported as:

AZURE_CODESIGNING_DLIB

allowing Objo Studio to invoke Azure Trusted Signing through Microsoft's signing library.


Windows signing configuration

Before publishing, the workflow writes the Azure signing configuration into project.json.

The following values are configured:

  • Azure Endpoint
  • Azure Account Name
  • Azure Certificate Profile Name
  • Azure Correlation ID
  • Timestamp URL
  • Package Publisher

Because these values are present, Objo Studio automatically signs every generated MSIX package during publishing.


Runtime identifiers

Typical runtime identifiers include:

Runtime identifier Platform
win-x64 64-bit Windows
win-arm64 ARM64 Windows
win-x86 32-bit Windows

Examples:

with:
  targets: "win-x64"

or

with:
  targets: "win-x64, win-arm64"

Whitespace surrounding target names is ignored automatically.


Correlation ID

The correlation ID is optional.

When not supplied, the workflow automatically generates one using:

  • application name
  • GitHub run ID
  • GitHub run attempt

Example:

MyGreatApp-1234567890-1

Timestamping

Timestamping is optional.

If azure-timestamp-url is supplied, it is written into project.json and Objo requests timestamping while signing.

If omitted, the timestamp field is left empty and Objo signs without timestamping.


Output directory

Default output directory:

%USERPROFILE%\Publish

Typical GitHub-hosted runner location:

C:\Users\runneradmin\Publish

Custom example:

with:
  output-directory: Documents\Releases

Result:

C:\Users\runneradmin\Documents\Releases

Generated artifacts

After publishing completes, the workflow searches recursively for every generated .msix package.

The packages are copied into:

artifacts

and uploaded using actions/upload-artifact.

Typical uploaded artifacts:

com.objo.app.mygreatapp_1.1.0.0_x64.msix
com.objo.app.mygreatapp_1.1.0.0_arm64.msix

Duplicate filenames are renamed automatically to avoid overwriting.


Example

name: ObjoPublisher Windows (Objo Signing)

on:
  workflow_dispatch:

jobs:
  publish:
    uses: madamov/ObjoPublisher/.github/workflows/publish_objo_windows_objosign.yml@v1

    with:
      solution-file: MyGreatApp.objosln
      project-file: Projects/MyGreatApp/project.json
      resource-artifact-name: release-resources
      application-name: MyGreatApp
      output-directory: Publish
      targets: "win-x64"
      artifact-name: mygreatapp-windows

      # Optional
      # objo-version: "26.7.1"
      # azure-correlation-id: "Release-42"

    secrets:
      objo-license: ${{ secrets.OBJO_LICENSE }}

      azure-endpoint: ${{ secrets.AZURE_ENDPOINT }}
      azure-account-name: ${{ secrets.AZURE_ACCOUNTNAME }}
      azure-certificate-profile-name: ${{ secrets.AZURE_CERTIFICATEPROFILENAME }}
      azure-package-publisher: ${{ secrets.AZURE_PACKAGEPUBLISHER }}

      # Optional
      azure-timestamp-url: ${{ secrets.AZURE_TIMESTAMPURL }}

Differences from publish_objo_windows.yml

Feature publish_objo_windows.yml publish_objo_windows_objosign.yml
MSIX generation Objo Studio Objo Studio
MSIX signing Azure Trusted Signing GitHub Action Objo Studio
Azure Artifact Signing Client Tools Not required Installed automatically
Azure.CodeSigning.Dlib.dll Not used Located automatically
Azure Tenant / Client credentials Required Not required
project.json Azure settings Cleared Fully populated
Uses azure/trusted-signing-action ✔ ✘
Objo invokes signtool.exe ✘ ✔

Notes

  • Objo Studio performs both publishing and signing.
  • Microsoft's Azure Artifact Signing Client Tools are installed automatically.
  • The workflow automatically locates Azure.CodeSigning.Dlib.dll.
  • No additional signing step is required after publishing.
  • Persistent Objo Studio licenses used with versions earlier than 26.8.4 are deactivated before the workflow finishes.
  • Objo Studio is cached by version.
  • Multiple Windows runtime identifiers are supported.
  • Timestamping is optional.

About

Contains GitHub action workflows you can use to automate publishing of applications made with Objo Studio

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors