Repository: mheap/pin-github-action (js)

Issue:
`-c, --comment <string>` should parse `<string>`-formatted comments
After pinning using `--comment=' {ref}'` it's not possible to re-run the same pinning command:

```
❯ npx pin-github-action --comment=' {ref}' .github/workflows/*.y*ml
Unable to find SHA for [some action]@ v3
```

Use case: After resolving a conflict with another branch which updated an action, I might have a few actions which need to be re-pinned.

Pull request:
Read pinned version from custom comment
#142 added support for writing custom comments, but I missed adding support for _reading_ custom comments.

This PR resolves #148 

Patch:
diff --git a/extractActions.js b/extractActions.js
index a60b5db..556cd2d 100644
--- a/extractActions.js
+++ b/extractActions.js
@@ -1,18 +1,18 @@
 let debug = () => {};
-module.exports = function (input, allowEmpty, log) {
+module.exports = function (input, allowEmpty, comment, log) {
   debug = log.extend("extract-actions");
   // Check if it's a composite action
   let runs = input.contents.items.filter((n) => n.key == "runs");
   if (runs.length) {
     debug("Processing composite action");
-    return extractFromComposite(input, allowEmpty);
+    return extractFromComposite(input, allowEmpty, comment);
   }
 
   debug("Processing workflow");
-  return extractFromWorkflow(input, allowEmpty);
+  return extractFromWorkflow(input, allowEmpty, comment);
 };
 
-function extractFromComposite(input, allowEmpty) {
+function extractFromComposite(input, allowEmpty, comment) {
   let runs = input.contents.items.filter((n) => n.key == "runs");
   let steps = runs[0].value.items.filter((n) => n.key == "steps");
 
@@ -23,12 +23,12 @@ function extractFromComposite(input, allowEmpty) {
   const actions = new Set();
   steps = steps[0].value.items;
   for (let step of steps) {
-    handleStep(actions, step.items);
+    handleStep(actions, step.items, comment);
   }
   return Array.from(actions);
 }
 
-function extractFromWorkflow(input, allowEmpty) {
+function extractFromWorkflow(input, allowEmpty, comment) {
   let actions = new Set();
 
   let jobs = input.contents.items.filter((n) => n.key == "jobs");
@@ -56,11 +56,11 @@ function extractFromWorkflow(input, allowEmpty) {
       }
 
       for (let step of steps[0].value.items) {
-        handleStep(actions, step.items);
+        handleStep(actions, step.items, comment);
       }
     } else {
       // It's a job that calls a reusable workflow
-      handleStep(actions, steps);
+      handleStep(actions, steps, comment);
     }
   }
 
@@ -71,7 +71,7 @@ function extractFromWorkflow(input, allowEmpty) {
   return Array.from(actions);
 }
 
-function handleStep(actions, items) {
+function handleStep(actions, items, comment) {
   const uses = items.filter((n) => n.key == "uses");
 
   for (let use of uses) {
@@ -87,7 +87,10 @@ function handleStep(actions, items) {
     }
 
     const details = parseAction(line);
-    let original = (use.value.comment || "").replace(" pin@", "");
+
+    comment = comment.replace("{ref}", "");
+
+    let original = (use.value.comment || "").replace(comment, "");
     if (!original) {
       original = details.currentVersion;
     }
diff --git a/index.js b/index.js
index 37f31bd..1ca2aeb 100644
--- a/index.js
+++ b/index.js
@@ -23,7 +23,7 @@ module.exports = async function (
   let workflow = YAML.parseDocument(input);
 
   // Extract list of actions
-  let actions = extractActions(workflow, allowEmpty, debug);
+  let actions = extractActions(workflow, allowEmpty, comment, debug);
 
   for (let i in actions) {
     // Should this action be updated?


Test patch:
diff --git a/extractActions.test.js b/extractActions.test.js
index 8c717cd..7c1f10f 100644
--- a/extractActions.test.js
+++ b/extractActions.test.js
@@ -2,8 +2,11 @@ const YAML = require("yaml");
 const debug = require("debug")("pin-github-action-test");
 
 const run = require("./extractActions");
-const extractActions = (input, allowEmpty) => {
-  return run.apply(null, [input, allowEmpty, debug]);
+const extractActions = (input, allowEmpty, comment) => {
+  if (!comment) {
+    comment = " pin@{ref}";
+  }
+  return run.apply(null, [input, allowEmpty, comment, debug]);
 };
 
 test("extracts a single version", () => {
@@ -61,6 +64,31 @@ test("extracts a pinned version", () => {
   ]);
 });
 
+test("extracts a pinned version with a custom comment", () => {
+  const input = YAML.parseDocument(`
+    name: PR
+    on:
+      - pull_request
+    jobs:
+      test-job:
+        runs-on: ubuntu-latest
+        steps:
+          - name: Test Action Step
+            uses: "mheap/test-action@abc123" # 1.4.0`);
+
+  const actual = extractActions(input, false, " {ref}");
+
+  expect(actual).toEqual([
+    {
+      owner: "mheap",
+      repo: "test-action",
+      path: "",
+      currentVersion: "abc123",
+      pinnedVersion: "1.4.0",
+    },
+  ]);
+});
+
 test("extracts a single version in a subfolder", () => {
   const input = convertToAst({
     name: "PR",