8 Commits

9 changed files with 48 additions and 23 deletions

View File

@@ -26,11 +26,12 @@ jobs:
run: | run: |
VERSION=${GITEA_REF_NAME} VERSION=${GITEA_REF_NAME}
echo "Building version $VERSION" echo "Building version $VERSION"
go build -ldflags "-s -w -X main.Version=$VERSION" -o myapp ./cmd/app go mod tidy
go build -ldflags "-s -w -X main.Version=$VERSION" -o lab-ca .
# 4. Install the tea CLI # 4. Install the tea CLI
- name: Install tea CLI - name: Install tea CLI
run: go install gitea.com/gitea/tea@latest run: go install code.gitea.io/tea@latest
# 5. Authenticate tea CLI # 5. Authenticate tea CLI
- name: Login to Gitea - name: Login to Gitea
@@ -50,4 +51,4 @@ jobs:
# 7. Upload binary to the release # 7. Upload binary to the release
- name: Upload binary - name: Upload binary
run: tea release upload $GITEA_REF_NAME ./myapp run: tea release upload $GITEA_REF_NAME lab-ca

View File

@@ -221,6 +221,16 @@ The tool checks that SANs are valid for the selected certificate type(s). Certif
See `examples/example-certificates.hcl` for a more advanced provisioning file with templates and variables. See `examples/example-certificates.hcl` for a more advanced provisioning file with templates and variables.
## Building the Tool
The repository includes a `build.sh` script to build the CLI tool. It updates the version in `version.go` and builds the binary.
To ignore changes made to `version.go` in Git, you can run:
```bash
git update-index --assume-unchanged version.go
```
--- ---
## Notes ## Notes

View File

@@ -7,6 +7,9 @@ else
VERSION="dev" VERSION="dev"
fi fi
# Hardcode the version into main.go
sed -i '' "s/^var Version = .*/var Version = \"$VERSION\"/" version.go
if echo $VERSION | grep -q 'dirty$'; then if echo $VERSION | grep -q 'dirty$'; then
echo "Building in development mode, output directory is set to 'build'." echo "Building in development mode, output directory is set to 'build'."
OUTPUT_DIR=build OUTPUT_DIR=build
@@ -19,4 +22,5 @@ else
fi fi
# Build the Lab CA binary with version information # Build the Lab CA binary with version information
go build -ldflags "-X main.Version=$VERSION" -o $OUTPUT_DIR/lab-ca # go build -ldflags "-X main.Version=$VERSION" -o $OUTPUT_DIR/lab-ca
go build -o $OUTPUT_DIR/lab-ca

4
ca.go
View File

@@ -72,7 +72,7 @@ func (def *CertificateDefinition) FillDefaultValues(defaults *CertificateDefault
def.Validity = defaults.Validity def.Validity = defaults.Validity
} }
if len(def.SAN) == 0 && len(defaults.SAN) > 0 { if len(def.SAN) == 0 && len(defaults.SAN) > 0 {
def.SAN = defaults.SAN def.SAN = append([]string(nil), defaults.SAN...)
} }
} }
@@ -705,7 +705,7 @@ func IssueCertificate(certDef CertificateDefinition, overwrite bool, dryRun bool
fmt.Printf("%s certificate and key for '%s' generated.\n", certDef.Type, certDef.Subject) fmt.Printf("%s certificate and key for '%s' generated.\n", certDef.Type, certDef.Subject)
if err := SaveCAState(); err != nil { if err := SaveCAState(); err != nil {
fmt.Printf("Error saving CA state: %v\n", err) fmt.Printf("Error saving CA state: %v", err)
} }
return nil return nil

View File

@@ -36,41 +36,42 @@ type CertificateRecord struct {
// Look for a certifcate by its name // Look for a certifcate by its name
func (c *CAState) FindByName(name string, all bool) *CertificateRecord { func (c *CAState) FindByName(name string, all bool) *CertificateRecord {
for _, cert := range c.Certificates { for i := range c.Certificates {
cert := &c.Certificates[i]
if cert.RevokedAt != "" && !all { if cert.RevokedAt != "" && !all {
continue continue
} }
if cert.Name == name { if cert.Name == name {
return &cert return cert
} }
} }
return nil return nil
} }
// Look for a certificate by its serial // Look for a certificate by its serial
func (c *CAState) FindBySerial(serial string, all bool) *CertificateRecord { func (c *CAState) FindBySerial(serial string, all bool) *CertificateRecord {
for _, cert := range c.Certificates { for i := range c.Certificates {
cert := &c.Certificates[i]
if cert.RevokedAt != "" && !all { if cert.RevokedAt != "" && !all {
continue continue
} }
if cert.Serial == serial { if cert.Serial == serial {
return &cert return cert
} }
} }
return nil return nil
} }
// func caStatePath() string {
// return filepath.Join(filepath.Dir(caConfigPath), caConfig.GetStateFileName())
// }
// LoadCAState loads the CA state from a JSON file // LoadCAState loads the CA state from a JSON file
func LoadCAState() error { func LoadCAState() error {
fmt.Printf("Loading CA state from %s\n", caStatePath) fmt.Printf("Loading CA state from %s\n", caStatePath)
f, err := os.Open(caStatePath) f, err := os.Open(caStatePath)
if err != nil { if err != nil {
if os.IsNotExist(err) {
// File does not exist, treat as empty state
caState = &CAState{}
return nil
}
return err return err
} }
defer f.Close() defer f.Close()
@@ -97,8 +98,7 @@ func SaveCAState() error {
// UpdateCAStateAfterIssue updates the CA state JSON after issuing a certificate // UpdateCAStateAfterIssue updates the CA state JSON after issuing a certificate
func (s *CAState) UpdateCAStateAfterIssue(serialType, name string, subject string, certType string, serialNumber any, validity time.Duration) error { func (s *CAState) UpdateCAStateAfterIssue(serialType, name string, subject string, certType string, serialNumber any, validity time.Duration) error {
if s == nil { if s == nil {
fmt.Fprintf(os.Stderr, "FATAL: CAState is nil in UpdateCAStateAfterIssue. This indicates a programming error.\n") return fmt.Errorf("CAState is nil in UpdateCAStateAfterIssue. This indicates a programming error.")
os.Exit(1)
} }
issued := time.Now().UTC().Format(time.RFC3339) issued := time.Now().UTC().Format(time.RFC3339)
expires := time.Now().Add(validity).UTC().Format(time.RFC3339) expires := time.Now().Add(validity).UTC().Format(time.RFC3339)
@@ -119,7 +119,7 @@ func (s *CAState) UpdateCAStateAfterIssue(serialType, name string, subject strin
func (s *CAState) AddCertificate(name, subject, certType, issued, expires, serial string) { func (s *CAState) AddCertificate(name, subject, certType, issued, expires, serial string) {
if s == nil { if s == nil {
fmt.Fprintf(os.Stderr, "FATAL: CAState is nil in AddCertificate. This indicates a programming error.\n") fmt.Fprintf(os.Stderr, "FATAL: CAState is nil in AddCertificate. This indicates a programming error.\n")
os.Exit(1) return
} }
rec := CertificateRecord{ rec := CertificateRecord{
Name: name, Name: name,
@@ -135,8 +135,7 @@ func (s *CAState) AddCertificate(name, subject, certType, issued, expires, seria
// RevokeCertificate revokes a certificate by serial number and reason code, updates state, and saves to disk // RevokeCertificate revokes a certificate by serial number and reason code, updates state, and saves to disk
func (s *CAState) RevokeCertificate(serial string, reason int) error { func (s *CAState) RevokeCertificate(serial string, reason int) error {
if s == nil { if s == nil {
fmt.Fprintf(os.Stderr, "FATAL: CAState is nil in RevokeCertificate. This indicates a programming error.\n") return fmt.Errorf("CAState is nil in RevokeCertificate. This indicates a programming error.")
os.Exit(1)
} }
revoked := false revoked := false
revokedAt := time.Now().UTC().Format(time.RFC3339) revokedAt := time.Now().UTC().Format(time.RFC3339)

View File

@@ -0,0 +1,3 @@
#!/bin/bash
git update-index --assume-unchanged version.go

View File

@@ -7,8 +7,6 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var Version = ""
// Global flags available to all commands // Global flags available to all commands
var overwrite bool var overwrite bool
var dryRun bool var dryRun bool

7
set-version.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
VERSION=${1:-$(git describe --tags --always --dirty 2>/dev/null || echo "dev")}
# Allow git to track changes to version.go
git update-index --no-assume-unchanged version.go
# Hardcode the version into main.go
sed -i '' "s/^var Version = .*/var Version = \"$VERSION\"/" version.go

3
version.go Normal file
View File

@@ -0,0 +1,3 @@
package main
var Version = "v0.3.2"