|
1 | 1 | import { Env, LogType } from '@basemaps/shared'; |
2 | | -import { Octokit } from '@octokit/core'; |
3 | | -import { Api } from '@octokit/plugin-rest-endpoint-methods/dist-types/types.js'; |
4 | | -import { restEndpointMethods } from '@octokit/plugin-rest-endpoint-methods'; |
5 | | - |
6 | | -export const owner = 'linz'; // The Owner of the Github repository |
7 | | -export const repo = 'basemaps-config'; // Github repository name |
8 | | -export const base = 'master'; // Base head name of repository |
9 | | - |
10 | | -export interface Job { |
11 | | - imagery: string; |
12 | | - tileMatrix: string; |
13 | | - content: string; |
14 | | -} |
15 | | - |
16 | | -export interface Blob { |
17 | | - path: string; |
18 | | - mode: '100644'; |
19 | | - type: 'blob'; |
20 | | - sha: string; |
21 | | -} |
| 2 | +import { execFileSync } from 'child_process'; |
22 | 3 |
|
23 | 4 | export class Github { |
24 | | - octokit: Api; |
| 5 | + repo: string; |
25 | 6 | logger: LogType; |
26 | 7 |
|
27 | | - constructor(logger: LogType) { |
| 8 | + constructor(repo: string, logger: LogType) { |
| 9 | + this.repo = repo; |
28 | 10 | this.logger = logger; |
29 | | - const token = Env.get(Env.GitHubToken); |
30 | | - if (token == null) throw new Error('Please set up github token environment variable.'); |
31 | | - this.octokit = restEndpointMethods(new Octokit({ auth: token })); |
32 | 11 | } |
33 | 12 |
|
34 | | - isOk = (s: number): boolean => s >= 200 && s <= 299; |
35 | | - |
36 | 13 | /** |
37 | | - * Get branch by name if exists |
| 14 | + * Clone the repository |
38 | 15 | * |
39 | | - * @returns {ref} github references or the new created branch |
40 | 16 | */ |
41 | | - async getBranch(ref: string): Promise<string | undefined> { |
42 | | - this.logger.info({ ref }, 'GitHub: Get branch'); |
43 | | - try { |
44 | | - const response = await this.octokit.rest.git.getRef({ owner, repo, ref }); |
45 | | - if (this.isOk(response.status)) return response.data.object.sha; |
46 | | - } catch { |
47 | | - this.logger.info({ ref }, 'GitHub: Brach Not Found'); |
48 | | - return; |
49 | | - } |
50 | | - return; |
| 17 | + clone(): void { |
| 18 | + const https = `https://github.com/${this.repo}.git`; |
| 19 | + this.logger.info({ repository: this.repo }, 'GitHub: Clone'); |
| 20 | + execFileSync('git', ['clone', https]).toString().trim(); |
51 | 21 | } |
52 | 22 |
|
53 | 23 | /** |
54 | | - * Create a new branch from the latest master branch |
| 24 | + * Get branch by name if exists, or create a new branch by name. |
55 | 25 | * |
56 | | - * @returns {ref} github references or the new created branch |
| 26 | + * @returns {branch} github references or the new created branch |
57 | 27 | */ |
58 | | - async createBranch(branch: string, ref: string): Promise<string> { |
59 | | - // Get the latest sha from master branch |
60 | | - const master = await this.octokit.rest.git.getRef({ owner, repo, ref: `heads/${base}` }); |
61 | | - if (!this.isOk(master.status)) throw new Error('Failed to get master head.'); |
62 | | - const sha = master.data.object.sha; |
63 | | - |
64 | | - // Create new branch from the latest master |
65 | | - this.logger.info({ branch }, 'GitHub: Create branch'); |
66 | | - const response = await this.octokit.rest.git.createRef({ owner, repo, ref: `refs/${ref}`, sha }); |
67 | | - if (!this.isOk(response.status)) throw new Error(`Failed to create branch ${branch}.`); |
68 | | - return sha; |
69 | | - } |
70 | | - |
71 | | - async createBlobs(content: string, path: string): Promise<Blob> { |
72 | | - // Create the blobs with the files content |
73 | | - this.logger.info({ path }, 'GitHub: Create blob'); |
74 | | - const blobRes = await this.octokit.rest.git.createBlob({ owner, repo, content, encoding: 'utf-8' }); |
75 | | - if (!this.isOk(blobRes.status)) throw new Error(`Failed to create data blob.`); |
76 | | - |
77 | | - const blobSha = blobRes.data.sha; |
78 | | - return { path, mode: '100644', type: 'blob', sha: blobSha }; |
| 28 | + getBranch(branch: string): string { |
| 29 | + this.logger.info({ branch }, 'GitHub: Get branch'); |
| 30 | + try { |
| 31 | + execFileSync('git', ['checkout', branch], { cwd: this.repo }).toString().trim(); |
| 32 | + this.logger.info({ branch }, 'GitHub: Branch Checkout'); |
| 33 | + return branch; |
| 34 | + } catch { |
| 35 | + this.logger.info({ branch }, 'GitHub: Create New Branch'); |
| 36 | + execFileSync('git', ['checkout', '-b', branch], { cwd: this.repo }).toString().trim(); |
| 37 | + return branch; |
| 38 | + } |
79 | 39 | } |
80 | 40 |
|
81 | 41 | /** |
82 | | - * Create a file imagery config file into basemaps-config/config/imagery and commit |
| 42 | + * Config github user email and user name |
| 43 | + * |
83 | 44 | */ |
84 | | - async commit(branch: string, ref: string, blobs: Blob[], message: string, sha: string): Promise<void> { |
85 | | - // Create a tree which defines the folder structure |
86 | | - const treeRes = await this.octokit.rest.git.createTree({ owner, repo, base_tree: sha, tree: blobs }); |
87 | | - if (!this.isOk(treeRes.status)) throw new Error(`Failed to create tree.`); |
88 | | - |
89 | | - const treeSha = treeRes.data.sha; |
90 | | - |
91 | | - // Create the commit |
92 | | - const commitRes = await this.octokit.rest.git.createCommit({ |
93 | | - owner, |
94 | | - repo, |
95 | | - message, |
96 | | - parents: [sha], |
97 | | - tree: treeSha, |
98 | | - }); |
99 | | - if (!this.isOk(commitRes.status)) throw new Error(`Failed to create commit.`); |
100 | | - |
101 | | - const commitSha = commitRes.data.sha; |
102 | | - |
103 | | - // Update the reference of your branch to point to the new commit SHA |
104 | | - const response = await this.octokit.rest.git.updateRef({ owner, repo, ref, sha: commitSha }); |
105 | | - if (!this.isOk(response.status)) throw new Error(`Failed to update branch ${branch} sha.`); |
| 45 | + configUser(): void { |
| 46 | + const email = Env.get('GIT_USER_EMAIL') ?? 'basemaps@linz.govt.nz'; |
| 47 | + const name = Env.get('GIT_USER_NAME') ?? 'basemaps[bot]'; |
| 48 | + this.logger.info({ repository: this.repo }, 'GitHub: Config User Email'); |
| 49 | + execFileSync('git', ['config', 'user.email', email], { cwd: this.repo }).toString().trim(); |
| 50 | + this.logger.info({ repository: this.repo }, 'GitHub: Config User Name'); |
| 51 | + execFileSync('git', ['config', 'user.name', name], { cwd: this.repo }).toString().trim(); |
106 | 52 | } |
107 | 53 |
|
108 | 54 | /** |
109 | | - * Create a new pull request from the given branch and return pull request number |
| 55 | + * Commit the changes to current branch |
| 56 | + * |
110 | 57 | */ |
111 | | - async createPullRequest(branch: string, title: string, draft: boolean): Promise<number> { |
112 | | - // Create pull request from the give head |
113 | | - const response = await this.octokit.rest.pulls.create({ owner, repo, title, head: branch, base, draft }); |
114 | | - if (!this.isOk(response.status)) throw new Error('Failed to create pull request.'); |
115 | | - this.logger.info({ branch, url: response.data.html_url }, 'GitHub: Create Pull Request'); |
116 | | - return response.data.number; |
| 58 | + commit(message: string): void { |
| 59 | + this.logger.info({ repository: this.repo }, 'GitHub: Commit all'); |
| 60 | + execFileSync('git', ['commit', '-am', `"${JSON.stringify(message)}"`], { cwd: this.repo }) |
| 61 | + .toString() |
| 62 | + .trim(); |
117 | 63 | } |
118 | 64 |
|
119 | 65 | /** |
120 | | - * Update a new pull request from pull request number |
| 66 | + * Push the local brach |
| 67 | + * |
121 | 68 | */ |
122 | | - async updatePullRequest(branch: string, title: string, pull_number: number): Promise<void> { |
123 | | - // Update pull request by given pull_number |
124 | | - const response = await this.octokit.rest.pulls.update({ owner, repo, pull_number, title, base }); |
125 | | - if (!this.isOk(response.status)) throw new Error('Failed to update pull request.'); |
126 | | - this.logger.info({ branch, pull_number }, 'GitHub: Update Pull Request'); |
| 69 | + push(): void { |
| 70 | + this.logger.info({ repository: this.repo }, 'GitHub: Push'); |
| 71 | + execFileSync('git', ['push', 'origin', 'HEAD'], { cwd: this.repo }).toString().trim(); |
127 | 72 | } |
128 | 73 | } |
0 commit comments