From 61bac52a23e41cb8e1f72128390ef570522f21ed Mon Sep 17 00:00:00 2001 From: Misha Kav Date: Sat, 8 Oct 2022 19:40:08 +0300 Subject: [PATCH 1/4] :beetle: update license in package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 18ea046..75e3810 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ }, "keywords": [], "author": "", - "license": "ISC", + "license": "MIT", "bugs": { "url": "https://github.com/Schneegans/dynamic-badges-action/issues" }, From aac224f23570d16a450b5aac92283def8ed9277d Mon Sep 17 00:00:00 2001 From: Misha Kav Date: Sat, 8 Oct 2022 19:40:48 +0300 Subject: [PATCH 2/4] :wrench: align version to new bump --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index fcd945e..34d6126 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "dynamic-badges-action", - "version": "1.0.0", + "version": "1.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 75e3810..d265915 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dynamic-badges-action", - "version": "1.0.0", + "version": "1.5.0", "description": "A GitHub Action which uses shields.io to create custom badges and uploads the to a gist.", "main": "index.js", "scripts": { From 2a87c9f45eabef09c67dbb99f765771228ab970a Mon Sep 17 00:00:00 2001 From: Misha Kav Date: Sat, 8 Oct 2022 20:34:55 +0300 Subject: [PATCH 3/4] :memo: add explnation to `updateIfChanged` --- README.md | 1 + action.yml | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/README.md b/README.md index a012cc2..1f52652 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ Parameter | Description `logoPosition` | The position of the logo. `style` | The style like "flat" or "social". `cacheSeconds` | The cache lifetime in seconds (must be greater than 300). +`updateIfChanged` | Default is `false`. If `true` will update the gist only if content changed. ### Color Range Parameters (optional) diff --git a/action.yml b/action.yml index 9d02190..44bb212 100644 --- a/action.yml +++ b/action.yml @@ -19,6 +19,10 @@ inputs: message: description: 'The right text of the badge' required: true + updateIfChanged: + description: 'If true will update the gist only if content changed' + default: 'false' + required: false labelColor: description: 'The left color of the badge' required: false From 4dbb581c4cb43bf5f02a068d12850bd32e68e832 Mon Sep 17 00:00:00 2001 From: Misha Kav Date: Sat, 8 Oct 2022 20:35:01 +0300 Subject: [PATCH 4/4] :tada: add ability to update gist only if changed --- index.js | 129 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 104 insertions(+), 25 deletions(-) diff --git a/index.js b/index.js index 773efc3..cebb41e 100644 --- a/index.js +++ b/index.js @@ -3,6 +3,49 @@ const http = require('https'); try { + function updatingGist(data) { + // Perform the actual request. The user agent is required as defined in + // https://developer.github.com/v3/#user-agent-required + const updateGistOptions = { + host: 'api.github.com', + path: '/gists/' + core.getInput('gistID'), + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Content-Length': data.length, + 'User-Agent': 'Schneegans', + 'Authorization': 'token ' + core.getInput('auth'), + } + }; + + return doRequest(updateGistOptions, data) + } + + function doRequest(options, data) { + return new Promise((resolve, reject) => { + const req = http.request(options, (res) => { + res.setEncoding('utf8'); + let responseBody = ''; + + res.on('data', (chunk) => { + responseBody += chunk; + }); + + res.on('end', () => { + const { statusCode, statusMessage } = res; + resolve({ statusCode, statusMessage, body: JSON.parse(responseBody) }); + }); + }); + + req.on('error', (err) => { + reject(err); + }); + + req.write(data) + req.end(); + }); + } + // This object will be stringified and uploaded to the gist. The // schemaVersion, label and message attributes are always required. All others // are optional and added to the content object only if they are given to the @@ -13,6 +56,8 @@ try { message: core.getInput('message') }; + const updateIfChanged = core.getInput('updateIfChanged'); + // Compute the message color based on the given inputs. const color = core.getInput('color'); const valColorRange = core.getInput('valColorRange'); @@ -64,6 +109,7 @@ try { const logoPosition = core.getInput('logoPosition'); const style = core.getInput('style'); const cacheSeconds = core.getInput('cacheSeconds'); + const filename = core.getInput('filename'); if (labelColor != '') { content.labelColor = labelColor; @@ -101,39 +147,72 @@ try { content.cacheSeconds = parseInt(cacheSeconds); } + let shouldUpdate = true; + // For the POST request, the above content is set as file contents for the // given filename. const request = JSON.stringify({ - files: {[core.getInput('filename')]: {content: JSON.stringify(content)}} + files: {[filename]: {content: JSON.stringify(content)}} }); + + if (updateIfChanged == 'true') { + const getGistOptions = { + host: 'api.github.com', + path: '/gists/' + core.getInput('gistID'), + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'User-Agent': 'Schneegans', + 'Authorization': 'token ' + core.getInput('auth'), + } + }; + + doRequest(getGistOptions, JSON.stringify({})).then(oldGist => { + if (oldGist.statusCode < 200 || oldGist.statusCode >= 400) { + // print the error, but don't fail the action + console.log( + 'Failed to get gist, response status code: ' + oldGist.statusCode + + ', status message: ' + oldGist.statusMessage); + } + + if (oldGist && oldGist.body && oldGist.body.files && oldGist.body.files[filename]) { + const oldContent = oldGist.body.files[filename].content; - // Perform the actual request. The user agent is required as defined in - // https://developer.github.com/v3/#user-agent-required - const req = http.request( - { - host: 'api.github.com', - path: '/gists/' + core.getInput('gistID'), - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Content-Length': request.length, - 'User-Agent': 'Schneegans', - 'Authorization': 'token ' + core.getInput('auth'), + if (oldContent === JSON.stringify(content)) { + console.log(`Content did not change, not updating gist at ${filename}`); + shouldUpdate = false; } - }, - res => { - if (res.statusCode < 200 || res.statusCode >= 400) { - core.setFailed( + } + + if (shouldUpdate) { + if (oldGist.body.files[filename]) { + console.log(`Content changed, updating gist at ${filename}`); + } else { + console.log(`Content didn't exist, creating gist at ${filename}`); + } + + updatingGist(request).then(res => { + if (res.statusCode < 200 || res.statusCode >= 400) { + core.setFailed( 'Failed to create gist, response status code: ' + res.statusCode + ', status message: ' + res.statusMessage); - } else { - console.log('Success!'); - } - }); - - req.write(request); - req.end(); - + } else { + console.log('Success!'); + } + }); + } + }); + } else { + updatingGist(request).then(res => { + if (res.statusCode < 200 || res.statusCode >= 400) { + core.setFailed( + 'Failed to create gist, response status code: ' + res.statusCode + + ', status message: ' + res.statusMessage); + } else { + console.log('Success!'); + } + }); + } } catch (error) { core.setFailed(error); }