Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an integration test or example on how to use the addOrUpdateRepoSecret function. #1607

Closed
raboley opened this issue Aug 17, 2020 · 5 comments
Closed

Comments

@raboley
Copy link
Contributor

@raboley raboley commented Aug 17, 2020

I wanted to use this library to push secrets from my env to my github repo easily, and eventually got it figured out. But It would be very helpful to have an example of how to do that since it requires sodiumlib which is extremely difficult to parse if you are trying to figure out the bare minimum needed to encrypt a secret for posting to github.

essentially what I had to do to update the repo's secret was

Authenticate with github

func GithubAuth() (context.Context, *github.Client, error) {
	token := os.Getenv("API_GITHUB_TOKEN")
	if token == "" {
		return nil, nil, errors.New(`no API_GITHUB_TOKNE was found in the environment variables.
This is needed to authenticate with github. Please generate a github token that has access to do what you are trying to do
and export it as an environment variable.

ex:
	export API_GITHUB_TOKEN="<token contents string>"
`)
	}
	ctx := context.Background()
	ts := oauth2.StaticTokenSource(
		&oauth2.Token{AccessToken: token},
	)
	tc := oauth2.NewClient(ctx, ts)

	client := github.NewClient(tc)
	return ctx, client, nil
}

Get the base64 encoded public key of the repo to encrypt a secret using sodiumlib

publicKey, _, err := client.Actions.GetRepoPublicKey(ctx, owner, repo)

encrypt the secret string with the public key

func encryptSecretWithPublicKey(publicKey *github.PublicKey, secretName string, secretValue string) (*github.EncryptedSecret, error) {
	decodedPublicKey, err := base64.StdEncoding.DecodeString(publicKey.GetKey())
	if err != nil {
		return nil, errors.New(fmt.Sprintf("base64.StdEncoding.DecodeString was unable to decode public key: %v", err))
	}

	secretBytes := []byte(secretValue)
	encryptedBytes, exit := sodium.CryptoBoxSeal(secretBytes, decodedPublicKey)
	if exit != 0 {
		return nil, errors.New("sodium.CryptoBoxSeal exited with non zero exit code")
	}

	encryptedString := base64.StdEncoding.EncodeToString(encryptedBytes)
	keyID := publicKey.GetKeyID()
	encryptedSecret := &github.EncryptedSecret{
		Name:           secretName,
		KeyID:          keyID,
		EncryptedValue: encryptedString,
	}
	return encryptedSecret, nil
}

bring it all together with AddRepoSecret function

func AddRepoSecret(owner string, repo string, secretName string, secretValue string) (string, error) {
	ctx, client, err := GithubAuth()
	if err != nil {
		return "", err
	}
	publicKey, _, err := client.Actions.GetRepoPublicKey(ctx, owner, repo)
	if err != nil {
		return "", err
	}

	encryptedSecret, err := encryptSecretWithPublicKey(publicKey, secretName, secretValue)
	if err != nil {
		return "", err
	}

	_, err = client.Actions.CreateOrUpdateRepoSecret(ctx, owner, repo, encryptedSecret)
	if err != nil {
		return "", errors.New(fmt.Sprintf("Actions.CreateOrUpdateRepoSecret returned error: %v", err))
	}

	return secretName, nil
}

Hopefully this helps someone, if there is a direction I should take I can work to contribute this back in some form or another.

@gmlewis
Copy link
Collaborator

@gmlewis gmlewis commented Aug 17, 2020

Thank you, @raboley !

Please check out our "example" directory: https://github.com/google/go-github/tree/master/example
and consider adding a new directory with a simple example showing what you did.
You should be able to see how the other examples were put together and do something similar.

Also, please make sure to read through our CONTRIBUTING.md file to get started on putting together a PR.

@vamsee47
Copy link

@vamsee47 vamsee47 commented Aug 17, 2020

good

@myungkwon
Copy link

@myungkwon myungkwon commented Aug 17, 2020

x

@raboley
Copy link
Contributor Author

@raboley raboley commented Sep 3, 2020

@gmlewis Thank you for the notes! Sorry for the delay, I have create PR #1626 to add an example of this the best I could. I signed the contributing agreement, and tried to follow any direction and other examples as I could! Due to mine requiring 3rd party libraries and more complexity than I would have liked the example isn't quite as simple as others, but hopefully it makes it clear enough. Open to any feedback!

@raboley
Copy link
Contributor Author

@raboley raboley commented Sep 12, 2020

closed by #1626

@raboley raboley closed this Sep 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants