Switch remote deploy to vendored source builds

Move remote deployment to a vendored source bundle built on the target host via Docker so redeploys no longer require local cross-compilation or host Go installation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
GitHub Actions
2026-05-08 12:19:18 +08:00
parent bb27566e38
commit c1a0fe2949
1320 changed files with 497125 additions and 11 deletions

View File

@@ -0,0 +1,233 @@
// Package toast wraps the lower-level wintoast api and provides an easy way
// to send and respond to toast notifications on Windows.
//
// First, setup your AppData vis SetAppData function. This will install your
// application metadata into the Windows Registry.
//
// Then, if you want in-process callback to be invoked upon user interaction,
// invoke SetActivationCallback.
//
// Finally, generate your notification by instantiation a toast.Notification
// and pushing it with Push method.
package toast
import (
"bytes"
"git.sr.ht/~jackmordaunt/go-toast/v2/tmpl"
"git.sr.ht/~jackmordaunt/go-toast/v2/wintoast"
)
// Notification
//
// The toast notification data. The following fields are strongly recommended;
// - AppID
// - Title
//
// If no toastAudio is provided, then the toast notification will be silent.
//
// The AppID is shown beneath the toast message (in certain cases), and above the notification within the Action
// Center - and is used to group your notifications together. It is recommended that you provide a "pretty"
// name for your app, and not something like "com.example.MyApp". It can be ellided if the value has already
// been set via SetAppData.
//
// If no Title is provided, but a Body is, the body will display as the toast notification's title -
// which is a slightly different font style (heavier).
//
// The Icon should be an absolute path to the icon (as the toast is invoked from a temporary path on the user's
// system, not the working directory).
//
// If you would like the toast to call an external process/open a webpage, then you can set ActivationArguments
// to the uri you would like to trigger when the toast is clicked. For example: "https://google.com" would open
// the Google homepage when the user clicks the toast notification.
// By default, clicking the toast just hides/dismisses it.
//
// The following would show a notification to the user letting them know they received an email, and opens
// gmail.com when they click the notification. It also makes the Windows 10 "mail" sound effect.
//
// toast := toast.Notification{
// AppID: "Google Mail",
// Title: email.Subject,
// Message: email.Preview,
// Icon: "C:/Program Files/Google Mail/icons/logo.png",
// ActivationArguments: "https://gmail.com",
// Audio: toast.Mail,
// }
//
// err := toast.Push()
type Notification struct {
// The name of your app. This value shows up in Windows Action Centre, so make it
// something readable for your users.
AppID string
// The main title/heading for the toast notification.
Title string
// The single/multi line message to display for the toast notification.
Body string
// An optional path to an image on the OS to display to the left of the title & message.
Icon string
// An optional crop style for the Icon.
IconCrop CropStyle
// An optional path to an image to display as a bold hero image.
HeroIcon string
// A color to show as the icon background.
IconBackgroundColor string
// Action to take when the notification is as a whole activated.
ActivationType ActivationType
// The activation/action arguments (invoked when the user clicks the notification).
// This is returned to the callback when activated.
ActivationArguments string
// Optional text input to display before the actions.
Inputs []Input
// Optional action buttons to display below the notification title & message.
Actions []Action
// The audio to play when displaying the toast
Audio toastAudio
// Whether to loop the audio (default false).
Loop bool
// How long the toast should show up for (short/long).
Duration toastDuration
// This is an absolute path to an executable that will launched by the
// Windows Runtime when the COM server is not running. This executable must be able
// to handle the -Embedding flag that Windows invokes it with.
ActivationExe string
}
// CropStyle specifies the hint-crop attribute for an image.
type CropStyle = string
const (
CropStyleEmpty CropStyle = ""
CropStyleSquare CropStyle = "square"
CropStyleCircle CropStyle = "circle"
)
// UserData contains user supplied data from the notification, such as text input
// or a selection.
type UserData = wintoast.UserData
// Input
//
// Defines an input element, generally a text input.
// See https://learn.microsoft.com/en-us/uwp/schemas/tiles/toastschema/element-input for more info.
//
// Inputs are by default textual, however if selections are supplied the input will be rendered
// as a select input.
type Input struct {
ID string
Title string
Placeholder string
Selections []InputSelection
}
// InputSelection
//
// Defines an input selection for use with select inputs.
// See https://learn.microsoft.com/en-us/uwp/schemas/tiles/toastschema/element-selection for more info.
type InputSelection struct {
ID string
Content string
}
// Action
//
// Defines an actionable button.
// See https://msdn.microsoft.com/en-us/windows/uwp/controls-and-patterns/tiles-and-notifications-adaptive-interactive-toasts for more info.
//
// toast.Action{toast.Protocol, "Open Maps", "bingmaps:?q=sushi"}
//
// TODO(jfm): we can likely support an activation callback directly in the Action.
type Action struct {
Type ActivationType
Content string
Arguments string
InputID string // optional ID of any related input, affects styling.
}
// Push the notification to the Windows Runtime via the COM API.
// Ensure [SetAppData] has been called prior to pushing notifications.
//
// notification := toast.Notification{
// AppID: "Example App",
// Title: "My notification",
// Message: "Some message about how important something is...",
// Icon: "go.png",
// Actions: []toast.Action{
// {"protocol", "I'm a button", ""},
// {"protocol", "Me too!", ""},
// },
// }
// err := notification.Push()
// if err != nil {
// log.Fatalln(err)
// }
func (n *Notification) Push() error {
n.applyDefaults()
xml, err := n.buildXML()
if err != nil {
return err
}
return wintoast.Push(n.AppID, xml, wintoast.PowershellFallback)
}
func (n *Notification) applyDefaults() {
if n.ActivationType == "" {
n.ActivationType = Foreground
}
if n.Duration == "" {
n.Duration = Short
}
if n.Audio == "" {
n.Audio = Default
}
}
func (n *Notification) buildXML() (string, error) {
var out bytes.Buffer
err := tmpl.XMLTemplate.Execute(&out, n)
if err != nil {
return "", err
}
return out.String(), nil
}
// SetActivationCallback sets the global activation callback.
//
// The first argument contains application defined data (embedded within the xml),
// which is how the callback knows which part of the toast was activated.
// Argument data is defined by `toast.Action.Arguments` on the notification.
//
// The second argument contains user defined data (input/selected by user).
// All elements of user input will be supplied here, even if the value is empty.
// User inputs correspond to all `toast.Input`s defined on the notification.
//
// This function will be invoked when a toast notification is interacted with.
//
// This will do nothing if the the powershell fallback is in-effect.
func SetActivationCallback(cb func(args string, data []UserData)) {
wintoast.SetActivationCallback(func(appUserModelId, invokedArgs string, userData []wintoast.UserData) {
cb(invokedArgs, userData)
})
}
type AppData = wintoast.AppData
// SetAppData sets application metadata in the Windows Registry.
// This is required to display the application name, as well as any branding.
// Registry is global state, hence it makes sense to set it global.
func SetAppData(data AppData) error {
return wintoast.SetAppData(data)
}