You've already forked autoversion
							
							first commit
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | node_modules | ||||||
							
								
								
									
										170
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,170 @@ | |||||||
|  | # Autoversion-action | ||||||
|  |  | ||||||
|  | This action will detect new version. | ||||||
|  |  | ||||||
|  | ### Tagging: Part of a Complete Deployment Solution | ||||||
|  | This action works well in combination with: | ||||||
|  |  | ||||||
|  | - [actions/create-release](https://github.com/actions/create-release) (Auto-release) | ||||||
|  | - [author/action-publish](https://github.com/author/action-publish) (Auto-publish JavaScript/Node modules) | ||||||
|  | - [author/action-rollback](https://github.com/author/action-rollback) (Auto-rollback releases on failures) | ||||||
|  |  | ||||||
|  | ## Usage | ||||||
|  |  | ||||||
|  | The following is an example `.gitea/workflows/main.yml` that will execute when a `push` to the `master` branch occurs. | ||||||
|  |  | ||||||
|  | ```yaml | ||||||
|  | name: Detect Tag | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - master | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |     - uses: actions/checkout@v3 | ||||||
|  |     - uses: butlerlogic/action-autotag@stable | ||||||
|  |       env: | ||||||
|  |         GITEA_TOKEN: "${{ secrets.GITEA_TOKEN }}" | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | To make this work, the workflow must have the checkout action _before_ the autotag action. | ||||||
|  |  | ||||||
|  | This **order** is important! | ||||||
|  |  | ||||||
|  | ```yaml | ||||||
|  | - uses: actions/checkout@v4 | ||||||
|  | - uses: butlerlogic/action-autotag@stable | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | **If the repository is not checked out first, the autotagger cannot find the source files.** | ||||||
|  |  | ||||||
|  | ## Configuration | ||||||
|  |  | ||||||
|  | The `GITEA_TOKEN` **must** be provided. Without this, it is not possible to create a new tag. Make sure the autotag action looks like the following example: | ||||||
|  |  | ||||||
|  | ```yaml | ||||||
|  | - uses: butlerlogic/action-autotag@stable | ||||||
|  |   env: | ||||||
|  |     GITEA_TOKEN: "${{ secrets.GITEA_TOKEN }}" | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | The action will automatically extract the token at runtime. **DO NOT MANUALLY ENTER YOUR TOKEN.** If you put the actual token in your workflow file, you'll make it accessible (in plaintext) to anyone who ever views the repository (it will be in your git history). | ||||||
|  |  | ||||||
|  | ## Optional Configuration Options | ||||||
|  |  | ||||||
|  | There are several options to customize how the tag is created. | ||||||
|  |  | ||||||
|  | ### root | ||||||
|  |  | ||||||
|  | Depending on the selected strategy, autotagger will look for the confgured identify file (i.e. `package.json`, `composer.json`, `Dockerfile`, etc) in the project root. If the file is located in a subdirectory, this option can be used to point to the correct file. | ||||||
|  |  | ||||||
|  | ```yaml | ||||||
|  | - uses: butlerlogic/action-autotag@1.0.0 | ||||||
|  |   env: | ||||||
|  |     GITEA_TOKEN: "${{ secrets.GITEA_TOKEN }}" | ||||||
|  |   with: | ||||||
|  |     strategy: regex # Optional since regex_pattern is defined | ||||||
|  |     root: "/path/to/subdirectory/my.file" | ||||||
|  |     regex_pattern: "version=([0-9\.])" | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | The version will be extracted by scanning the content of `/path/to/subdirectory/my.file` for a string like `version=1.0.0`. See the `regex_pattern` option for more details. | ||||||
|  |  | ||||||
|  | ### regex_pattern | ||||||
|  |  | ||||||
|  | An optional attribute containing the regular expression used to extract the version number. | ||||||
|  |  | ||||||
|  | ```yaml | ||||||
|  | - uses: butlerlogic/action-autotag@1.0.0 | ||||||
|  |   env: | ||||||
|  |     GITEA_TOKEN: "${{ secrets.GITEA_TOKEN }}" | ||||||
|  |   with: | ||||||
|  |     regex_pattern: "version=([0-9\.]{5}([-\+][\w\.0-9]+)?)" | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | This attribute is used as the first argument of a [RegExp](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp) object. The first "group" (i.e. what's in the main set of parenthesis/the whole version number) will be used as the version number. For an example, see this [working example](https://regexr.com/51r8j). | ||||||
|  |  | ||||||
|  | The pattern described in this example is a simplistic one. If you need a more explicit one the [complete semver pattern](https://regex101.com/r/vkijKf/1/) is: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | ^((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)$ | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | As of `1.1.2`, JavaScript named patterns are supported, where the group named `version` will be used to populate the tag. For example: | ||||||
|  |  | ||||||
|  | ```yaml | ||||||
|  | - uses: butlerlogic/action-autotag@1.0.0 | ||||||
|  |   env: | ||||||
|  |     GITEA_TOKEN: "${{ secrets.GITEA_TOKEN }}" | ||||||
|  |   with: | ||||||
|  |     regex_pattern: "(version=)(?<version>[\d+\.]{3}([-\+][\w\.0-9]+)?)" | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### tag_prefix | ||||||
|  |  | ||||||
|  | By default, [semantic versioning](https://semver.org/) is used, such as `1.0.0`. A prefix can be used to add text before the tag name. For example, if `tag_prefix` is set to `v`, then the tag would be labeled as `v1.0.0`. | ||||||
|  |  | ||||||
|  | ```yaml | ||||||
|  | - uses: butlerlogic/action-autotag@1.0.0 | ||||||
|  |   env: | ||||||
|  |     GITEA_TOKEN: "${{ secrets.GITEA_TOKEN }}" | ||||||
|  |   with: | ||||||
|  |     tag_prefix: "v" | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### tag_message | ||||||
|  |  | ||||||
|  | This is the annotated commit message associated with the tag. By default, a changelog will be generated from the commits between the latest tag and the current reference (HEAD). Setting this option will override the message. | ||||||
|  |  | ||||||
|  | ```yaml | ||||||
|  | - uses: butlerlogic/action-autotag@1.0.0 | ||||||
|  |   env: | ||||||
|  |     GITEA_TOKEN: "${{ secrets.GITEA_TOKEN }}" | ||||||
|  |   with: | ||||||
|  |     tag_message: "Custom message goes here." | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### commit_message_template | ||||||
|  |  | ||||||
|  | By default, a changelog is generated, containing the commit messages since the last release. The message is generated by applying a commit message template to each commit's data attributes. | ||||||
|  |  | ||||||
|  | ```yaml | ||||||
|  | - uses: butlerlogic/action-autotag@1.0.0 | ||||||
|  |   env: | ||||||
|  |     GITEA_TOKEN: "${{ secrets.GITEA_TOKEN }}" | ||||||
|  |   with: | ||||||
|  |     commit_message_template: "({{sha}} by {{author}}) {{message}}" | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Optional data points: | ||||||
|  |  | ||||||
|  | 1. `number` The commit number (relevant to the overall list) | ||||||
|  | 1. `message` The commit message. | ||||||
|  | 1. `author` The author of the commit. | ||||||
|  | 1. `sha` The SHA value representing the commit. | ||||||
|  |  | ||||||
|  | The default is `{{number}}) {{message}} ({{author}})\nSHA: {{sha}}\n`. | ||||||
|  |  | ||||||
|  | _Example output:_ | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | 1) Update README.md (coreybutler) | ||||||
|  | (SHA: c5e09fc45106a4b27b8f4598fb79811b589a4684) | ||||||
|  |  | ||||||
|  | 2) Added metadoc capability to introspect the shell/commands. (coreybutler) | ||||||
|  | (SHA: b690be366a5636d51b1245a1b39c86102ddb8a81) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Developer Notes | ||||||
|  |  | ||||||
|  | If you are building an action that runs after this one, be aware this action produces several [outputs](https://help.github.com/en/articles/metadata-syntax-for-github-actions#outputs): | ||||||
|  |  | ||||||
|  | 1. `tagname` will be empty if no tag was created, or it will be the value of the new tag. | ||||||
|  | 1. `tagcreated`: `yes` or `no`. | ||||||
|  | 1. `version` will be the extracted/provided version. | ||||||
|  |  | ||||||
|  | --- | ||||||
							
								
								
									
										32
									
								
								action.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								action.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | name: "autoversion" | ||||||
|  | description: "Automatically detect new tags for new versions" | ||||||
|  | author: "Al Azhar" | ||||||
|  | branding: | ||||||
|  |   icon: "tag" | ||||||
|  |   color: "blue" | ||||||
|  | inputs: | ||||||
|  |   filepath: | ||||||
|  |     description: Autotag will look for the appropriate file in in this location (relative to project root). | ||||||
|  |     required: true | ||||||
|  |     default: './' | ||||||
|  |   regex_pattern: | ||||||
|  |     description: An optional attribute containing the regular expression used to extract the version number. | ||||||
|  |     required: true | ||||||
|  |   tag_prefix: | ||||||
|  |     description: By default, package.json uses semantic versioning, such as "1.0.0". A prefix can be used to add text before the tag name. For example, if tag_prefx is set to "v", then the tag would be labeled as "v1.0.0". | ||||||
|  |     required: false | ||||||
|  |   log_template: | ||||||
|  |     description: "The commit message template (per commit). Default is `{{number}}) {{message}} ({{author}})\nSHA: {{sha}}\n`" | ||||||
|  |     required: false | ||||||
|  | outputs: | ||||||
|  |   tagname: | ||||||
|  |     description: Returns the new tag value. Empty if a tag is not created. | ||||||
|  |   changelog: | ||||||
|  |     description: Returns list commit message from previous commit. | ||||||
|  |   version: | ||||||
|  |     description: The version, as defined in package.json or explicitly set in the input. | ||||||
|  |   prerelease: | ||||||
|  |     description: Is the new version prerelease. | ||||||
|  | runs: | ||||||
|  |   using: "node20" | ||||||
|  |   main: "dist/index.js" | ||||||
							
								
								
									
										35777
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										35777
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										3
									
								
								dist/package.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								dist/package.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | { | ||||||
|  |   "type": "module" | ||||||
|  | } | ||||||
							
								
								
									
										98
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @ -0,0 +1,98 @@ | |||||||
|  | { | ||||||
|  |   "name": "autoversion", | ||||||
|  |   "version": "1.0.0", | ||||||
|  |   "lockfileVersion": 3, | ||||||
|  |   "requires": true, | ||||||
|  |   "packages": { | ||||||
|  |     "": { | ||||||
|  |       "name": "autoversion", | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@actions/core": "^1.10.0", | ||||||
|  |         "gitea-js": "1.22.0", | ||||||
|  |         "semver": "^7.3.8" | ||||||
|  |       }, | ||||||
|  |       "devDependencies": { | ||||||
|  |         "@vercel/ncc": "^0.38.1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@actions/core": { | ||||||
|  |       "version": "1.10.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.1.tgz", | ||||||
|  |       "integrity": "sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@actions/http-client": "^2.0.1", | ||||||
|  |         "uuid": "^8.3.2" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@actions/http-client": { | ||||||
|  |       "version": "2.2.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.1.tgz", | ||||||
|  |       "integrity": "sha512-KhC/cZsq7f8I4LfZSJKgCvEwfkE8o1538VoBeoGzokVLLnbFDEAdFD3UhoMklxo2un9NJVBdANOresx7vTHlHw==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "tunnel": "^0.0.6", | ||||||
|  |         "undici": "^5.25.4" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@fastify/busboy": { | ||||||
|  |       "version": "2.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", | ||||||
|  |       "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=14" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@vercel/ncc": { | ||||||
|  |       "version": "0.38.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.38.1.tgz", | ||||||
|  |       "integrity": "sha512-IBBb+iI2NLu4VQn3Vwldyi2QwaXt5+hTyh58ggAMoCGE6DJmPvwL3KPBWcJl1m9LYPChBLE980Jw+CS4Wokqxw==", | ||||||
|  |       "dev": true, | ||||||
|  |       "bin": { | ||||||
|  |         "ncc": "dist/ncc/cli.js" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/gitea-js": { | ||||||
|  |       "version": "1.22.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/gitea-js/-/gitea-js-1.22.0.tgz", | ||||||
|  |       "integrity": "sha512-vG3yNU2NKX7vbsqHH5U3q0u3OmWWh3c4nvyWtx022jQEDJDZP47EoGurXCmOhzvD5AwgUV6r+lVAz+Fa1dazgg==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/semver": { | ||||||
|  |       "version": "7.6.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", | ||||||
|  |       "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", | ||||||
|  |       "bin": { | ||||||
|  |         "semver": "bin/semver.js" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=10" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/tunnel": { | ||||||
|  |       "version": "0.0.6", | ||||||
|  |       "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", | ||||||
|  |       "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=0.6.11 <=0.7.0 || >=0.7.3" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/undici": { | ||||||
|  |       "version": "5.28.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", | ||||||
|  |       "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@fastify/busboy": "^2.0.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=14.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/uuid": { | ||||||
|  |       "version": "8.3.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", | ||||||
|  |       "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", | ||||||
|  |       "bin": { | ||||||
|  |         "uuid": "dist/bin/uuid" | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | { | ||||||
|  |   "name": "autoversion", | ||||||
|  |   "version": "1.0.0", | ||||||
|  |   "description": "Automatically create a tag whenever the version changes in file version", | ||||||
|  |   "main": "main.js", | ||||||
|  |   "scripts": { | ||||||
|  |     "start": "node ./src/main.js", | ||||||
|  |     "package": "ncc build ./src/main.js -o dist" | ||||||
|  |   }, | ||||||
|  |   "keywords": [ | ||||||
|  |     "actions", | ||||||
|  |     "node", | ||||||
|  |     "setup" | ||||||
|  |   ], | ||||||
|  |   "author": "Al Azhar", | ||||||
|  |   "type": "module", | ||||||
|  |   "dependencies": { | ||||||
|  |     "@actions/core": "^1.10.0", | ||||||
|  |     "semver": "^7.3.8", | ||||||
|  |     "gitea-js": "1.22.0" | ||||||
|  |   }, | ||||||
|  |   "devDependencies": { | ||||||
|  |     "@vercel/ncc": "^0.38.1" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								src/lib/regex.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/lib/regex.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | import { existsSync, statSync, readFileSync } from 'fs' | ||||||
|  | import { resolve } from 'path' | ||||||
|  |  | ||||||
|  | export default class Regex { | ||||||
|  |   constructor (root = './', pattern) { | ||||||
|  |     root = resolve(root) | ||||||
|  |  | ||||||
|  |     if (statSync(root).isDirectory()) { | ||||||
|  |       throw new Error(`${root} is a directory. The Regex tag identification strategy requires a file.`) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (!existsSync(root)) { | ||||||
|  |       throw new Error(`"${root}" does not exist.`) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     this.content = readFileSync(root).toString() | ||||||
|  |  | ||||||
|  |     let content = pattern.exec(this.content) | ||||||
|  |     if (!content) { | ||||||
|  |       this._version = null | ||||||
|  |       // throw new Error(`Could not find pattern matching "${pattern.toString()}" in "${root}".`) | ||||||
|  |     } else if (content.groups && content.groups.version) { | ||||||
|  |       this._version = content.groups.version | ||||||
|  |     } else { | ||||||
|  |       this._version = content[1] | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   get version () { | ||||||
|  |     return this._version | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   get versionFound () { | ||||||
|  |     return this._version !== null | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								src/lib/setup.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/lib/setup.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | import core from '@actions/core' | ||||||
|  | import { readdirSync } from 'fs' | ||||||
|  | import path from 'path' | ||||||
|  |  | ||||||
|  | export default class Setup { | ||||||
|  |   static debug () { | ||||||
|  |     // Metadate for debugging | ||||||
|  |     // core.debug( | ||||||
|  |     //   ` Available environment variables:\n -> ${Object.keys(process.env) | ||||||
|  |     //     .map(i => i + ' :: ' + process.env[i]) | ||||||
|  |     //     .join('\n -> ')}` | ||||||
|  |     // ) | ||||||
|  |  | ||||||
|  |     const dir = readdirSync(path.resolve(process.env.GITHUB_WORKSPACE), { withFileTypes: true }) | ||||||
|  |       .map(entry => { | ||||||
|  |         return `${entry.isDirectory() ? '> ' : '  - '}${entry.name}` | ||||||
|  |       }) | ||||||
|  |       .join('\n') | ||||||
|  |  | ||||||
|  |       console.log({dir}) | ||||||
|  |  | ||||||
|  |     core.debug(` Working Directory: ${process.env.GITHUB_WORKSPACE}:\n${dir}`) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static requireAnyEnv () { | ||||||
|  |     for (const arg of arguments) { | ||||||
|  |       if (!process.env.hasOwnProperty(arg)) { | ||||||
|  |         return | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     throw new Error('At least one of the following environment variables is required: ' + Array.slice(arguments).join(', ')) | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										109
									
								
								src/lib/tag.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								src/lib/tag.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | import core from '@actions/core' | ||||||
|  | import os from 'os' | ||||||
|  | import { giteaApi } from 'gitea-js' | ||||||
|  |  | ||||||
|  | const gitea = giteaApi(process.env.GITEA_URL, { | ||||||
|  |   token: process.env.GITEA_TOKEN, // generate one at https://gitea.example.com/user/settings/applications | ||||||
|  |   customFetch: fetch, | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | // Get owner and repo from context of payload that triggered the action | ||||||
|  | const [ owner, repo ] = process.env.GITHUB_REPOSITORY.split('/') | ||||||
|  |  | ||||||
|  | export default class Tag { | ||||||
|  |   constructor (prefix, version) { | ||||||
|  |     this.prefix = prefix | ||||||
|  |     this.version = version | ||||||
|  |     this._tags = null | ||||||
|  |     this._exists = null | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   get name () { | ||||||
|  |     return `${this.prefix.trim()}${this.version.trim()}` | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   get message() { | ||||||
|  |     return (async () => { | ||||||
|  |       try { | ||||||
|  |         let tags = await this.getTags() | ||||||
|  |    | ||||||
|  |         if (tags.length === 0) { | ||||||
|  |           return `Version ${this.version}` | ||||||
|  |         } | ||||||
|  |    | ||||||
|  |         const changelog = await gitea.repos.repoCompareDiff(owner, repo, tags.shift().name + "..." + process.env.GITHUB_REF_NAME ?? 'main' ) | ||||||
|  |    | ||||||
|  |         const tpl = (core.getInput('log_template', { required: false }) || '').trim() | ||||||
|  |    | ||||||
|  |         return changelog.data.commits | ||||||
|  |           .map( | ||||||
|  |             (commit, i) => { | ||||||
|  |               if (tpl.length > 0) { | ||||||
|  |                 return tpl | ||||||
|  |                   .replace(/\{\{\s?(number)\s?\}\}/gi, i + 1) | ||||||
|  |                   .replace(/\{\{\s?(message)\s?\}\}/gi, commit.commit.message) | ||||||
|  |                   .replace(/\{\{\s?(author)\s?\}\}/gi, commit.hasOwnProperty('author') ? (commit.author.hasOwnProperty('login') ? commit.author.login : '') : '') | ||||||
|  |                   .replace(/\{\{\s?(sha)\s?\}\}/gi, commit.sha) | ||||||
|  |                   .trim() + '\n' | ||||||
|  |               } else { | ||||||
|  |                 return `${i === 0 ? '\n' : ''}${i + 1}) ${commit.commit.message}${ | ||||||
|  |                   commit.hasOwnProperty('author') | ||||||
|  |                     ? commit.author.hasOwnProperty('login') | ||||||
|  |                       ? ' (' + commit.author.login + ')' | ||||||
|  |                       : '' | ||||||
|  |                     : '' | ||||||
|  |                 }\n(SHA: ${commit.sha})\n` | ||||||
|  |               } | ||||||
|  |             }) | ||||||
|  |           .join('\n') | ||||||
|  |       } catch (e) { | ||||||
|  |         core.warning('Failed to generate changelog from commits: ' + e.message + os.EOL) | ||||||
|  |         return `Version ${this.version}` | ||||||
|  |       } | ||||||
|  |     })(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   get prerelease () { | ||||||
|  |     return /([0-9\.]{5}(-[\w\.0-9]+)?)/i.test(this.version) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   get previous () { | ||||||
|  |     return (async () => { | ||||||
|  |       try { | ||||||
|  |         const tags = await this.getTags() | ||||||
|  |  | ||||||
|  |         return tags.shift().name; | ||||||
|  |       } catch(e) { | ||||||
|  |         return "0.0.0"; | ||||||
|  |       } | ||||||
|  |     })(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async getTags () { | ||||||
|  |     if (this._tags !== null) { | ||||||
|  |       return this._tags.data | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     this._tags = await gitea.repos.repoListTags(owner, repo) | ||||||
|  |  | ||||||
|  |     return this._tags.data | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async exists () { | ||||||
|  |     if (this._exists !== null) { | ||||||
|  |       return this._exists | ||||||
|  |     } | ||||||
|  |     const currentTag = this.name | ||||||
|  |     const tags = await this.getTags() | ||||||
|  |  | ||||||
|  |     for (const tag of tags) { | ||||||
|  |       if (tag.name === currentTag) { | ||||||
|  |         this._exists = true | ||||||
|  |         return true | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     this._exists = false | ||||||
|  |     return false | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										85
									
								
								src/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/main.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,85 @@ | |||||||
|  | import * as core from '@actions/core' | ||||||
|  | import os from 'os' | ||||||
|  | import semver from 'semver' | ||||||
|  | import Setup from './lib/setup.js' | ||||||
|  | import Tag from './lib/tag.js' | ||||||
|  | import Regex from './lib/regex.js' | ||||||
|  |  | ||||||
|  | async function run () { | ||||||
|  |   try { | ||||||
|  |     Setup.debug() | ||||||
|  |     Setup.requireAnyEnv('GITEA_TOKEN', 'INPUT_GITEA_TOKEN')     | ||||||
|  |  | ||||||
|  |     // Identify the root directory to use for auto-identifying a tag version | ||||||
|  |     const filepath = core.getInput('filepath', { required: true }) | ||||||
|  |  | ||||||
|  |     // Retrieve the Regex pattern | ||||||
|  |     const pattern = core.getInput('regex_pattern', { required: true }) | ||||||
|  |  | ||||||
|  |     core.info(`filepath : ${ filepath }`) | ||||||
|  |     core.info(`regex_pattern : ${ pattern }`) | ||||||
|  |  | ||||||
|  |     // Extract the version number using the supplied Regex     | ||||||
|  |     let version = (new Regex(filepath, new RegExp(pattern, 'gim'))).version | ||||||
|  |  | ||||||
|  |     if (!version) { | ||||||
|  |       throw new Error(`No version identified extraction with the /${ pattern }/gim pattern.`) | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     core.info(`version ${ version } detected`) | ||||||
|  |  | ||||||
|  |     const [major, minor, patch, pre] = version.split(".") | ||||||
|  |     version = `${major}.${minor}.${patch}${pre ? "-beta." + pre : ""}` | ||||||
|  |  | ||||||
|  |     core.info(`version translated to ${ version }`) | ||||||
|  |  | ||||||
|  |     // Configure a tag using the identified version | ||||||
|  |     const tag = new Tag( | ||||||
|  |       core.getInput('tag_prefix', { required: false }), | ||||||
|  |       version | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     // Get min | ||||||
|  |     const minVersion = await tag.previous | ||||||
|  |      | ||||||
|  |     core.info(`Previous version ${ minVersion }`) | ||||||
|  |  | ||||||
|  |     // Ensure that version and minVersion are valid SemVer strings | ||||||
|  |     const versionSemVer = semver.coerce(version, { includePrerelease: pre}) | ||||||
|  |     const minVersionSemVer = semver.coerce(minVersion , { includePrerelease: pre}) | ||||||
|  |  | ||||||
|  |     if (!minVersionSemVer) { | ||||||
|  |       core.info(`Skipping min version check. ${minVersion} is not valid SemVer`) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if(!versionSemVer) { | ||||||
|  |       core.info(`Skipping min version check. ${version} is not valid SemVer`) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (minVersionSemVer && versionSemVer && semver.lt(versionSemVer, minVersionSemVer)) { | ||||||
|  |       core.info(`Version "${version}" is lower than minimum "${minVersion}"`) | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     core.notice(`Recognized "${version}"`) | ||||||
|  |     core.setOutput('version', version) | ||||||
|  |     core.debug(` Detected version ${version}`) | ||||||
|  |  | ||||||
|  |     // Check for existance of tag and abort (short circuit) if it already exists. | ||||||
|  |     if (await tag.exists()) { | ||||||
|  |       core.warning(`"${tag.name}" tag already exists.` + os.EOL) | ||||||
|  |       core.setOutput('tagname', '') | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // The tag setter will autocorrect the message if necessary. | ||||||
|  |     core.setOutput('changelog', await tag.message) | ||||||
|  |     core.setOutput('prerelease', tag.prerelease ? 'yes' : 'no') | ||||||
|  |     core.setOutput('tagname', tag.name) | ||||||
|  |   } catch (error) { | ||||||
|  |     core.setFailed(error.message + '\n' + error.stack) | ||||||
|  |     core.setOutput('tagname', '') | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | run() | ||||||
							
								
								
									
										8
									
								
								src/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |   "name": "autoversion", | ||||||
|  |   "version": "1.0.0", | ||||||
|  |   "description": "", | ||||||
|  |   "main": "main.js", | ||||||
|  |   "author": "Al Azhar", | ||||||
|  |   "type": "module" | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user