git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/selfupdate/relaese.go (about)

     1  package selfupdate
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  
     9  	"git.sr.ht/~pingoo/stdx/filex"
    10  	"git.sr.ht/~pingoo/stdx/zign"
    11  )
    12  
    13  type CreateReleaseInput struct {
    14  	// Name of the project. e.g. myapp
    15  	Name string
    16  	// Version of the release of the project. e.g. 1.1.52
    17  	Version string
    18  	Channel string
    19  	Files   []string
    20  	// ZignPrivateKey is the base64 encoded zign privateKey, encrypted with password
    21  	ZignPrivateKey string
    22  	ZignPassword   string
    23  }
    24  
    25  type Release struct {
    26  	Name            string
    27  	ChannelManifest ChannelManifest
    28  	ZignManifest    zign.Manifest
    29  }
    30  
    31  func CreateRelease(ctx context.Context, info CreateReleaseInput) (release Release, err error) {
    32  	release = Release{
    33  		Name: info.Name,
    34  		ChannelManifest: ChannelManifest{
    35  			Name:    info.Name,
    36  			Channel: info.Channel,
    37  			Version: info.Version,
    38  		},
    39  	}
    40  
    41  	signInput := make([]zign.SignInput, len(info.Files))
    42  	for index, file := range info.Files {
    43  		fileExists := false
    44  		var fileHandle *os.File
    45  		filename := filepath.Base(file)
    46  
    47  		fileExists, err = filex.Exists(file)
    48  		if err != nil {
    49  			err = fmt.Errorf("selfupdate: checking if file exists (%s): %w", file, err)
    50  			return
    51  		}
    52  
    53  		if !fileExists {
    54  			err = fmt.Errorf("selfupdate: file does not exist: %s", file)
    55  			return
    56  		}
    57  
    58  		fileHandle, err = os.Open(file)
    59  		if err != nil {
    60  			err = fmt.Errorf("opening file (%s): %w", file, err)
    61  			return
    62  		}
    63  		defer func(fileToClose *os.File) {
    64  			fileToClose.Close()
    65  		}(fileHandle)
    66  		fileSignInput := zign.SignInput{
    67  			Filename: filename,
    68  			Reader:   fileHandle,
    69  		}
    70  		signInput[index] = fileSignInput
    71  	}
    72  
    73  	signatures, err := zign.SignMany(info.ZignPrivateKey, info.ZignPassword, signInput)
    74  	if err != nil {
    75  		return
    76  	}
    77  
    78  	release.ZignManifest = zign.GenerateManifest(signatures)
    79  
    80  	return
    81  }