diff --git a/README.md b/README.md index 0b795a9..961a7ec 100644 --- a/README.md +++ b/README.md @@ -63,3 +63,13 @@ _This section covers how to contribute to this app. You don't need to read furth - `PRIVATE_KEY`: The private key of the GitHub App. You can get this from the GitHub app settings. The default app is [here](https://github.com/apps/optic-release-automation) - After the steps above are configured, go to `Actions` in your GitHub repo and run the CD workflow that is created in the folder `.github/workflows/cd.yaml`. The file is already configured with the action to deploy the cloud run service using the secrets that were created in the step above. - Once the workflow run, go to you GCP Account and open the "Cloud Run" page to see the details of the deployed service. + +## Testing changes locally +_This section covers how to run the app locally using ngrok to test your changes while developing a new feature or debugging an issue_ + +- Create a new github app and add the following permissions: + - `Contents`: Read and write + - `Pull requests`: Read and write +- Then go to `Install App` and install it on your repository +- Start the server and run `ngrok http 3000` on your local machine and get the public URL. This will be your API url, which needs to be set as the webhook URL on your github app and to be passed as the `api-url` input for the `optic-release-automation-action`. +- You should also pass the name of your bot as the `app-name` to the action. This is used after a PR is merged to check whether it was created by optic and whether we should proceed running the action on that PR diff --git a/index.test.js b/index.test.js index 3ad80cb..0686136 100644 --- a/index.test.js +++ b/index.test.js @@ -58,3 +58,51 @@ test('create pr', async t => { t.same(response.statusCode, 200) }) + +test('create release', async t => { + const mockedRepo = { repo: 'smn-repo', owner: 'salmanm' } + + const getAccessTokenStub = sinon.stub().resolves('some-token') + const createDraftReleaseStub = sinon.stub().resolves('some-token') + + const app = await setup(async server => { + server.addHook('onRequest', async req => { + req.auth = { ...mockedRepo } + }) + server.decorate('github', { + getAccessToken: getAccessTokenStub, + createDraftRelease: createDraftReleaseStub, + }) + }) + + const response = await app.inject({ + method: 'POST', + headers: { + authorization: 'token gh-token', + 'content-type': 'application/json', + }, + url: '/release', + body: JSON.stringify({ + target: 'commit-hash', + version: 'v9.9.9', + }), + }) + + t.same(getAccessTokenStub.callCount, 1) + t.ok(getAccessTokenStub.calledWithExactly('salmanm', 'smn-repo')) + + t.same(createDraftReleaseStub.callCount, 1) + t.ok( + createDraftReleaseStub.calledWithExactly( + { + version: 'v9.9.9', + target: 'commit-hash', + owner: 'salmanm', + repo: 'smn-repo', + }, + 'some-token' + ) + ) + + t.same(response.statusCode, 200) +}) diff --git a/lib/github.js b/lib/github.js index ca87b56..fc4bd9b 100644 --- a/lib/github.js +++ b/lib/github.js @@ -66,12 +66,13 @@ async function githubPlugin(app, options) { return github.rest.pulls.create(opts) } - async function createDraftRelease({ owner, repo, version }, token) { + async function createDraftRelease({ owner, repo, version, target }, token) { const github = new Octokit({ auth: token }) return github.rest.repos.createRelease({ owner, repo, tag_name: version, + target_commitish: target, generate_release_notes: true, draft: true, }) diff --git a/lib/routes.js b/lib/routes.js index 4825273..2ba4643 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -15,7 +15,8 @@ const prSchema = { const createReleaseSchema = { body: S.object() .additionalProperties(false) // important - .prop('version', S.string().required()), + .prop('version', S.string().required()) + .prop('target', S.string()), } const publishReleaseSchema = {