From 52100c89dd056e1a9161c46cf06829d22ce8cd44 Mon Sep 17 00:00:00 2001
From: CrazyMax <crazy-max@users.noreply.github.com>
Date: Mon, 6 Dec 2021 15:40:44 +0100
Subject: [PATCH] fix: handle raw statement for semver pre-release

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
---
 __tests__/meta.test.ts | 42 ++++++++++++++++++++++++++++++++++++++++++
 dist/index.js          | 19 ++++++++++++++++++-
 src/meta.ts            | 18 +++++++++++++++++-
 3 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/__tests__/meta.test.ts b/__tests__/meta.test.ts
index 034f2de..58cdd54 100644
--- a/__tests__/meta.test.ts
+++ b/__tests__/meta.test.ts
@@ -31,6 +31,19 @@ beforeEach(() => {
   });
 });
 
+describe('isRawStatement', () => {
+  // prettier-ignore
+  test.each([
+    ['{{ raw }}.{{ version }}', false],
+    ['{{ version }},{{raw }.', false],
+    ['{{ raw }}', true],
+    ['{{ raw}}', true],
+    ['{{raw}}', true],
+  ])('given %p pattern ', async (pattern: string, expected: boolean) => {
+    expect(Meta.isRawStatement(pattern)).toEqual(expected);
+  });
+});
+
 const tagsLabelsTest = async (name: string, envFile: string, inputs: Inputs, exVersion: Version, exTags: Array<string>, exLabels: Array<string>) => {
   process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
   const context = github.context();
@@ -1658,6 +1671,35 @@ describe('tag', () => {
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
+    [
+      'tag31',
+      'event_tag_v2.0.8-beta.67.env',
+      {
+        images: ['org/app', 'ghcr.io/user/app'],
+        tags: [
+          `type=semver,pattern={{raw}}`
+        ]
+      } as Inputs,
+      {
+        main: 'v2.0.8-beta.67',
+        partial: [],
+        latest: false
+      } as Version,
+      [
+        'org/app:v2.0.8-beta.67',
+        'ghcr.io/user/app:v2.0.8-beta.67'
+      ],
+      [
+        "org.opencontainers.image.title=Hello-World",
+        "org.opencontainers.image.description=This your first repo!",
+        "org.opencontainers.image.url=https://github.com/octocat/Hello-World",
+        "org.opencontainers.image.source=https://github.com/octocat/Hello-World",
+        "org.opencontainers.image.version=v2.0.8-beta.67",
+        "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
+        "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
+        "org.opencontainers.image.licenses=MIT"
+      ]
+    ],
   ])('given %p with %p event', tagsLabelsTest);
 });
 
diff --git a/dist/index.js b/dist/index.js
index 625c27e..e21525c 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -526,7 +526,12 @@ class Meta {
             includePrerelease: true
         });
         if (semver.prerelease(vraw)) {
-            vraw = this.setValue(handlebars.compile('{{version}}')(sver), tag);
+            if (Meta.isRawStatement(tag.attrs['pattern'])) {
+                vraw = this.setValue(handlebars.compile(tag.attrs['pattern'])(sver), tag);
+            }
+            else {
+                vraw = this.setValue(handlebars.compile('{{version}}')(sver), tag);
+            }
         }
         else {
             vraw = this.setValue(handlebars.compile(tag.attrs['pattern'])(sver), tag);
@@ -671,6 +676,18 @@ class Meta {
         }
         return version;
     }
+    static isRawStatement(pattern) {
+        try {
+            const hp = handlebars.parseWithoutProcessing(pattern);
+            if (hp.body.length == 1 && hp.body[0].type == 'MustacheStatement') {
+                return hp.body[0]['path']['parts'].length == 1 && hp.body[0]['path']['parts'][0] == 'raw';
+            }
+        }
+        catch (err) {
+            return false;
+        }
+        return false;
+    }
     setValue(val, tag) {
         if (tag.attrs.hasOwnProperty('prefix')) {
             val = `${this.setGlobalExp(tag.attrs['prefix'])}${val}`;
diff --git a/src/meta.ts b/src/meta.ts
index 7a86c20..b04e95f 100644
--- a/src/meta.ts
+++ b/src/meta.ts
@@ -143,7 +143,11 @@ export class Meta {
       includePrerelease: true
     });
     if (semver.prerelease(vraw)) {
-      vraw = this.setValue(handlebars.compile('{{version}}')(sver), tag);
+      if (Meta.isRawStatement(tag.attrs['pattern'])) {
+        vraw = this.setValue(handlebars.compile(tag.attrs['pattern'])(sver), tag);
+      } else {
+        vraw = this.setValue(handlebars.compile('{{version}}')(sver), tag);
+      }
     } else {
       vraw = this.setValue(handlebars.compile(tag.attrs['pattern'])(sver), tag);
       latest = true;
@@ -307,6 +311,18 @@ export class Meta {
     return version;
   }
 
+  public static isRawStatement(pattern: string): boolean {
+    try {
+      const hp = handlebars.parseWithoutProcessing(pattern);
+      if (hp.body.length == 1 && hp.body[0].type == 'MustacheStatement') {
+        return hp.body[0]['path']['parts'].length == 1 && hp.body[0]['path']['parts'][0] == 'raw';
+      }
+    } catch (err) {
+      return false;
+    }
+    return false;
+  }
+
   private setValue(val: string, tag: tcl.Tag): string {
     if (tag.attrs.hasOwnProperty('prefix')) {
       val = `${this.setGlobalExp(tag.attrs['prefix'])}${val}`;