Help us shape the future of Go! Take the 2026 Go Developer Survey

dekopin

package module
v0.0.0-...-6e7591f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 9, 2026 License: MIT Imports: 15 Imported by: 0

README

Dekopin

Dekopin is a command-line tool for managing Google Cloud Run deployments, revisions, and traffic routing. It provides an efficient workflow for deploying Cloud Run services with revision tagging and traffic management.

Features

  • Deploy new Cloud Run revisions with or without traffic
  • Create and manage revision tags
  • Switch traffic between revisions
  • Support for multiple deployment environments (local, GitHub Actions, Cloud Build)
  • YAML configuration format
  • Built-in timeout handling (default 120 seconds)
  • Consistent revision naming using commit hashes

Installation

go install github.com/iwashi623/dekopin/cmd/dekopin@latest

Configuration

Dekopin uses a YAML configuration file named dekopin.yml by default. The structure of the configuration file is as follows:

project: your-gcp-project-id
region: gcp-region
service: your-cloud-run-service-name
runner: github-actions  # or: cloud-build, local

Usage

Global Flags

The following flags can be used with any subcommand:

--project    GCP project ID
--region     GCP region
--service    Cloud Run service name
--runner     Runner type (github-actions, cloud-build, local)
--file, -f   Path to configuration file (default: dekopin.yml)
Tag Naming Rules

Tags in Dekopin must follow these rules:

  • Must consist of only lowercase alphanumeric characters and hyphens (a-z, 0-9, -)
  • Cannot contain uppercase letters, periods, underscores, spaces, or special characters
  • Empty tags are handled differently depending on the runner type:
    • For GitHub Actions and Cloud Build: Automatically generates a tag based on the reference
    • For local runner: Empty tags are not allowed and will result in an error

Examples of valid tags:

  • production
  • staging
  • release-v1
  • v1-0-0
  • feature-123

Examples of invalid tags:

  • Production (contains uppercase)
  • staging.1 (contains period)
  • test_tag (contains underscore)
  • tag with spaces (contains spaces)
Subcommands
deploy

Deploy a new revision with traffic directed to it.

dekopin deploy --image [IMAGE_URL]

Options:

  • --image, -i (required): Container image URL (e.g., gcr.io/project/image:tag)
  • --tag, -t: Tag name for the new revision (must follow tag naming rules)
  • --create-tag: Create a revision tag after deployment
  • --remove-tags: Remove all revision tags before deployment

Examples:

# Deploy with a specific image
dekopin deploy --image gcr.io/project/image:latest

# Deploy and create a tag
dekopin deploy --image gcr.io/project/image:latest --create-tag --tag release-v1
create-revision

Create a new revision without directing traffic to it. If the runner is GitHub Actions or Cloud Build, the revision name will use the first 7 characters of the commit hash.

dekopin create-revision --image [IMAGE_URL]

Options:

  • --image, -i (required): Container image URL

Example:

# Create a new revision with no traffic
dekopin create-revision --image gcr.io/project/image:v2
create-tag

Assign a tag to an existing revision. The tag must follow the naming rules specified above.

dekopin create-tag --tag [TAG_NAME] --revision [REVISION_NAME]

Options:

  • --tag, -t: Tag name to create (must follow tag naming rules)
  • --revision: Revision name to tag (default is latest)
  • --update-traffic: Update traffic to the tagged revision after deployment
  • --remove-tags: Remove all existing revision tags before creating the new tag

Examples:

# Tag the latest revision
dekopin create-tag --tag production

# Tag a specific revision
dekopin create-tag --tag staging --revision service-abcdef

# Tag a revision and direct traffic to it
dekopin create-tag --tag production --update-traffic

# Create a tag, making it the only tag by removing other tags
dekopin create-tag --tag production --remove-tags
remove-tag

Remove a tag from a revision.

dekopin remove-tag --tag [TAG_NAME]

Options:

  • --tag, -t (required): Tag name to remove

Example:

# Remove a tag
dekopin remove-tag --tag old-release
sr-deploy (Switch Revision Deploy)

Switch traffic to a specific revision.

dekopin sr-deploy --revision [REVISION_NAME]

Options:

  • --revision: Revision name to direct traffic to

Example:

# Direct all traffic to a specific revision
dekopin sr-deploy --revision service-abcdef
st-deploy (Switch Tag Deploy)

Switch traffic to a revision with a specific tag. The tag must already exist and follow the tag naming rules.

dekopin st-deploy --tag [TAG_NAME]

Options:

  • --tag, -t (required): Tag name to direct traffic to
  • --remove-tags: Remove all revision tags except the deployment target revision tag

Examples:

# Direct all traffic to the tagged revision
dekopin st-deploy --tag production

# Switch to tagged revision and clean up other tags
dekopin st-deploy --tag production --remove-tags

CI/CD Integration

GitHub Actions

Dekopin automatically detects GitHub Actions environments and can use environment variables for tag names or commit hashes. The first 7 characters of the commit hash are used for revision naming.

Example workflow:

name: Deploy to Cloud Run

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.23'
          
      - name: Install Dekopin
        run: go install github.com/iwashi623/dekopin/cmd/dekopin@latest
        
      - name: Deploy to Cloud Run
        run: dekopin deploy --image gcr.io/project/image:${{ github.sha }}
Google Cloud Build

Dekopin also supports Cloud Build integration using build environment variables. If the commit hash is 7 characters or fewer, it will be used as is; if longer, only the first 7 characters are used.

Example cloudbuild.yaml:

steps:
  - name: 'golang'
    entrypoint: 'go'
    args: ['install', 'github.com/iwashi623/dekopin/cmd/dekopin@latest']
  
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'gcr.io/$PROJECT_ID/image:$COMMIT_SHA', '.']
  
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', 'gcr.io/$PROJECT_ID/image:$COMMIT_SHA']
  
  - name: 'golang'
    entrypoint: 'dekopin'
    args: ['deploy', '--image', 'gcr.io/$PROJECT_ID/image:$COMMIT_SHA']

Validation

Dekopin includes validation for various input values:

  • Tags must consist of lowercase alphanumeric characters and hyphens (e.g., release-v1, v1-0-0)
  • Commands have appropriate required flags
  • Input values are validated before execution

Troubleshooting

Common Errors
  • Timeout Errors: By default, Dekopin has a 120-second timeout. For long-running operations, consider increasing this value in your code.
  • Tag Format Errors: If you receive errors about invalid tag formats, ensure your tags follow the naming rules (lowercase alphanumeric and hyphens only).

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Index

Constants

View Source
const (
	RUNNER_GITHUB_ACTIONS = "github-actions"
	RUNNER_CLOUD_BUILD    = "cloud-build"
	RUNNER_LOCAL          = "local"

	ENV_GITHUB_REF      = "GITHUB_REF"
	ENV_CLOUD_BUILD_REF = "REF_NAME"

	ENV_GITHUB_SHA      = "GITHUB_SHA"
	ENV_CLOUD_BUILD_SHA = "COMMIT_SHA"
)
View Source
const (
	SERVICE_FULL_NAME_FORMAT  = "projects/%s/locations/%s/services/%s"
	REVISION_FULL_NAME_FORMAT = "projects/%s/locations/%s/services/%s/revisions/%s"
)
View Source
const (
	COMMIT_HASH_LENGTH = 7
)
View Source
const (
	CREATE_TAG_DEFAULT_REVISION = "LATEST"
)
View Source
const (
	DEPLOY_DEFAULT_REVISION = "LATEST"
)
View Source
const (
	SWITCH_REVISION_DEFAULT_REVISION = "LATEST"
)
View Source
const (
	TIMEOUT = 120 * time.Second
)

Variables

View Source
var (
	ErrGetCommitHashInLocal = &GetCommitHashErrorInLocal{
		Message: "failed to get commit hash in local",
	}
)

Functions

func CreateRevisionTagName

func CreateRevisionTagName(ctx context.Context, tag string) (string, error)

func GetCommitHash

func GetCommitHash(ctx context.Context) (string, error)

func GetRunnerRef

func GetRunnerRef(ctx context.Context) (string, error)

func Run

func Run(ctx context.Context) int

func SetCmdOption

func SetCmdOption(ctx context.Context, cmdOption *CmdOption) context.Context

func SetDekopinCommand

func SetDekopinCommand(ctx context.Context, cmd DekopinCommand) context.Context

func SetGCloud

func SetGCloud(ctx context.Context, gcloud GCloud) context.Context

func ValidateTag

func ValidateTag(tag string) error

Types

type CmdOption

type CmdOption struct {
	Project string
	Region  string
	Service string
	Runner  string
}

func GetCmdOption

func GetCmdOption(ctx context.Context) (*CmdOption, error)

func NewCmdOption

func NewCmdOption(ctx context.Context, config *DekopinConfig, cmd *cobra.Command) (*CmdOption, error)

func (*CmdOption) Validate

func (c *CmdOption) Validate() error

type DekopinCommand

type DekopinCommand interface {
	GetFileByFlag() (string, error)
	GetProjectByFlag() (string, error)
	GetRegionByFlag() (string, error)
	GetServiceByFlag() (string, error)
	GetRunnerByFlag() (string, error)
	GetImageByFlag() (string, error)
	GetTagByFlag() (string, error)
	GetRevisionByFlag() (string, error)
	GetCreateTagByFlag() (bool, error)
	GetRemoveTagsByFlag() (bool, error)
	GetUpdateTrafficByFlag() (bool, error)
}

func GetDekopinCommand

func GetDekopinCommand(ctx context.Context) (DekopinCommand, error)

func NewDekopinCommand

func NewDekopinCommand(cmd *cobra.Command) DekopinCommand

type DekopinConfig

type DekopinConfig struct {
	Project string `yaml:"project"`
	Region  string `yaml:"region"`
	Service string `yaml:"service"`
	Runner  string `yaml:"runner"`
}

type DeployCommandFlags

type DeployCommandFlags struct {
	Image            string
	Tag              string
	ShouldCreateTag  bool
	ShouldRemoveTags bool
}

type GCloud

type GCloud interface {
	CreateRevision(ctx context.Context, imageName string, commitHash string) error          // Create a revision
	CreateRevisionTag(ctx context.Context, revisionTag string, revisionName string) error   // Assign a tag to a revision
	RemoveRevisionTag(ctx context.Context, revisionTag string) error                        // Remove a tag from a revision
	RemoveRevisionTags(ctx context.Context, revisionTags []string) error                    // Remove tags from a revision
	Deploy(ctx context.Context, imageName string, commitHash string, useTraffic bool) error // Deploy a revision
	UpdateTrafficToLatestRevision(ctx context.Context) error                                // Update traffic to the latest revision
	UpdateTrafficToRevision(ctx context.Context, revisionName string) error                 // Update traffic to the specified revision
	UpdateTrafficToRevisionTag(ctx context.Context, tag string) error                       // Update traffic to the specified tag
	DeployWithTraffic(ctx context.Context, imageName string, commitHash string) error       // Deploy with traffic
	GetActiveRevisionTags(ctx context.Context) ([]string, error)                            // Get active revision tags
	GetRevision(ctx context.Context, revisionName string) (*runpb.Revision, error)          // Get a revision
}

func GetGCloud

func GetGCloud(ctx context.Context) (GCloud, error)

func NewGCloud

func NewGCloud(stdout io.Writer, stderr io.Writer, servicesClient *run.ServicesClient, revisionsClient *run.RevisionsClient) GCloud

type GetCommitHashErrorInLocal

type GetCommitHashErrorInLocal struct {
	Message string
}

func (*GetCommitHashErrorInLocal) Error

func (e *GetCommitHashErrorInLocal) Error() string

Directories

Path Synopsis
cmd
dekopin command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL