├── .github
├── FUNDING.yml
└── workflows
│ ├── ci.yml
│ └── issue.yml
├── .gitignore
├── .husky
└── pre-commit
├── .lintstagedrc
├── LICENSE
├── README.md
├── action.yml
├── dist
└── index.js
├── package.json
├── renovate.json
├── src
├── index.ts
└── utils.ts
├── test
└── overwrite.file.md
└── tsconfig.json
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | ko_fi: jaywcjlove
2 | buy_me_a_coffee: jaywcjlove
3 | custom: ["https://www.paypal.me/kennyiseeyou", "https://jaywcjlove.github.io/#/sponsor"]
4 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on:
3 | push:
4 | branches:
5 | - main
6 |
7 | jobs:
8 | deploy:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v4
12 | - uses: actions/setup-node@v4
13 | with:
14 | node-version: 20
15 |
16 | - run: npm install
17 | - run: npm run build
18 | # - run: mkdir -p build
19 |
20 | - name: Generate Contributors Images
21 | uses: jaywcjlove/github-action-contributors@main
22 | id: contributors
23 |
24 | - name: Overwrite test/overwrite.file.md
25 | # uses: github-action-modify-file-content@main
26 | uses: ./
27 | with:
28 | path: test/overwrite.file.md
29 | body: "{{date:YYYY-MM-DD HH:mm:ss}}"
30 | overwrite: 'true'
31 |
32 | - name: Modify test test/overwrite.file.md
33 | # uses: jaywcjlove/github-action-modify-file-content@main
34 | uses: ./
35 | with:
36 | branch: test
37 | path: test/overwrite.file.md
38 | body: "{{date:YYYY-MM-DD HH:mm:ss}}"
39 | overwrite: 'true'
40 |
41 | - name: Modify README.md
42 | # uses: jaywcjlove/github-action-modify-file-content@main
43 | uses: ./
44 | with:
45 | path: README.md
46 | body: "{{date:YYYY-MM-DD HH:mm:ss}}"
47 |
48 | - name: Modify README.md
49 | # uses: jaywcjlove/github-action-modify-file-content@main
50 | uses: ./
51 | with:
52 | openDelimiter: ''
53 | closeDelimiter: ''
54 | path: README.md
55 | body: "different `GAMFC_TABEL` & `GAMFC_TABEL-END` (test)"
56 |
57 |
58 | - name: Modify CONTRIBUTING
59 | uses: ./
60 | with:
61 | path: README.md
62 | trim_whitespace: false
63 | openDelimiter: ''
64 | closeDelimiter: ''
65 | message: 'chore: update contributors'
66 | body: |
67 | ${{steps.contributors.outputs.htmlList}}
68 |
69 | # - name: Converts Markdown to HTML
70 | # uses: jaywcjlove/markdown-to-html-cli@main
71 | # with:
72 | # output: build/index.html
73 | # github-corners: https://github.com/jaywcjlove/github-action-modify-file-content
74 | # favicon: data:image/svg+xml,
75 |
76 | - name: Create idoc config
77 | run: |
78 | cat > idoc.yml << EOF
79 | site: "Modify File Content {{version}}"
80 | menus:
81 | Home: index.html
82 | Apps:
83 | url: https://jaywcjlove.github.io/#/app
84 | target: __blank
85 | Sponsor:
86 | url: https://jaywcjlove.github.io/#/sponsor
87 | target: __blank
88 | footer: |
89 | Sponsor •
90 | Create Tag •
91 | Contributors •
92 | Read File Content •
93 | Generated Badges
94 |
95 | Released under the MIT License. Copyright © {{idocYear}} Kenny Wong
96 | Generated by idoc v{{idocVersion}}
97 |
98 | EOF
99 |
100 | - run: npm install idoc@1 -g
101 | - run: idoc
102 |
103 | - name: Is a tag/release created auto?
104 | id: create_tag
105 | uses: jaywcjlove/create-tag-action@main
106 | with:
107 | # test: '[R|r]elease[d]\s+[v|V]\d(\.\d+){0,2}'
108 | package-path: ./package.json
109 |
110 | - name: get tag version
111 | id: tag_version
112 | uses: jaywcjlove/changelog-generator@main
113 |
114 | - name: gh-pages README.md
115 | working-directory: dist
116 | run: |
117 | cat > README.md << EOF
118 | Website: https://jaywcjlove.github.io/github-action-modify-file-content
119 |
120 | TEST: 2022-11-29 01:44:16
121 | EOF
122 |
123 | - name: Deploy
124 | uses: peaceiris/actions-gh-pages@v4
125 | with:
126 | commit_message: ${{steps.tag_version.outputs.tag}} ${{ github.event.head_commit.message }}
127 | github_token: ${{ secrets.GITHUB_TOKEN }}
128 | publish_dir: ./dist
129 |
130 | - name: Generate Changelog
131 | id: changelog
132 | uses: jaywcjlove/changelog-generator@main
133 | with:
134 | head-ref: ${{steps.create_tag.outputs.version}}
135 | filter: '[R|r]elease[d]\s+[v|V]\d(\.\d+){0,2}'
136 |
137 | - name: Create Release
138 | uses: jaywcjlove/create-tag-action@main
139 | with:
140 | # test: '[R|r]elease[d]\s+[v|V]\d(\.\d+){0,2}'
141 | package-path: ./package.json
142 | release: true
143 | body: |
144 | [](https://jaywcjlove.github.io/#/sponsor)
145 |
146 | Documentation ${{ steps.changelog.outputs.tag }}: https://raw.githack.com/jaywcjlove/github-action-modify-file-content/${{ steps.changelog.outputs.gh-pages-short-hash }}/index.html
147 | Comparing Changes: ${{ steps.changelog.outputs.compareurl }}
148 |
149 | ${{ steps.changelog.outputs.changelog }}
150 |
151 | ```yml
152 | - name: Modify README.md
153 | uses: jaywcjlove/github-action-modify-file-content@main
154 | with:
155 | path: README.md
156 | ```
157 |
158 | `README.md` file content
159 |
160 | ```markdown
161 | update time 2022-10-26 14:39:35
162 | ```
163 |
164 | Replace the content between `` and
165 | ``.
--------------------------------------------------------------------------------
/.github/workflows/issue.yml:
--------------------------------------------------------------------------------
1 | name: fix issue
2 | on:
3 | push:
4 | branches:
5 | - issue
6 |
7 | jobs:
8 | test:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v4
12 | - uses: actions/setup-node@v4
13 | with:
14 | node-version: 20
15 |
16 | - run: npm install
17 | - run: npm run build
18 | - run: mkdir -p build
19 |
20 | - name: Modify gh-pages README.md
21 | # uses: github-action-modify-file-content@main
22 | uses: ./
23 | with:
24 | path: README.md
25 | branch: gh-pages
26 | body: "{{date:YYYY-MM-DD HH:mm:ss}}"
27 |
28 |
29 | - name: Overwrite test/overwrite.file.md
30 | # uses: github-action-modify-file-content@main
31 | uses: ./
32 | with:
33 | path: test/overwrite.file.md
34 | branch: issue
35 | body: "{{date:YYYY-MM-DD HH:mm:ss}}"
36 | overwrite: 'true'
37 |
38 | - name: Overwrite test/overwrite.file.md
39 | # uses: github-action-modify-file-content@main
40 | uses: ./
41 | with:
42 | path: test/overwrite.file2.md
43 | branch: test
44 | body: "{{date:YYYY-MM-DD HH:mm:ss}}"
45 | overwrite: 'true'
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | lib
3 | node_modules
4 |
5 | npm-debug.log*
6 | lerna-debug.log
7 | yarn-error.log
8 | package-lock.json
9 |
10 | .DS_Store
11 | .cache
12 | .vscode
13 | .idea
14 | .env
15 |
16 | *.mpassword
17 | *.bak
18 | *.tem
19 | *.temp
20 | #.swp
21 | *.*~
22 | ~*.*
23 |
24 | # IDEA
25 | *.iml
26 | *.ipr
27 | *.iws
28 | .idea/
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | npx --no lint-staged
2 | git add dist/
--------------------------------------------------------------------------------
/.lintstagedrc:
--------------------------------------------------------------------------------
1 | {
2 | "*.ts": [
3 | "npm run build"
4 | ]
5 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 小弟调调™
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Modify File Content
2 | ===
3 |
4 | [](https://jaywcjlove.github.io/#/sponsor)
5 | [](https://github.com/jaywcjlove/github-action-modify-file-content/actions/workflows/ci.yml)
6 |
7 | Replace text content and submit content
8 |
9 | Here is the example: update time 2025-05-12 17:15:59
10 |
11 | Here is the different delimiter example: different `GAMFC_TABEL` & `GAMFC_TABEL-END` (test)
12 |
13 | ## Inputs
14 |
15 | | Name | Required | Default | Description |
16 | | -------- | -------- | -------- | -------- |
17 | | `token` | ✅ | `${{ github.token }}` | GitHub Token used to authenticate API requests. [Why?](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token#about-the-github_token-secret) |
18 | | `body` | ✅ | — | The content to insert between delimiters in the target file. |
19 | | `trim_whitespace` | ❌ | `true` | Trim leading and trailing whitespace in `body`. |
20 | | `path` | ✅ | — | File path to be modified. |
21 | | `branch` | ❌ | `${{ github.ref_name }}` | Branch to commit changes to. |
22 | | `ref` | ❌ | Default branch (usually `master`) | The target commit, branch, or tag. |
23 | | `overwrite` | ❌ | `false` | Whether to overwrite the entire file. |
24 | | `sync_local_file` | ❌ | `true` | Whether to sync the file from the local content. |
25 | | `message` | ❌ | `doc: update .` | Commit message. |
26 | | `committer_name` | ❌ | `github-actions[bot]` | Name used for the Git commit author. |
27 | | `committer_email` | ❌ | `github-actions[bot]@users.noreply.github.com` | Email used for the Git commit author. |
28 | | `openDelimiter` | ❌ | `2025-05-12 17:15:59` | End delimiter for content replacement. |
29 |
30 | ## Outputs
31 |
32 | - `content` text file content
33 |
34 | ## Example Usage
35 |
36 | ```yml
37 | - name: Modify README.md
38 | uses: jaywcjlove/github-action-modify-file-content@main
39 | with:
40 | path: README.md
41 | ```
42 |
43 | `README.md` file content
44 |
45 | ```markdown
46 | update time 2025-05-12 17:15:59
47 | ```
48 |
49 | Replace the content between `2025-05-12 17:15:59`.
50 |
51 | ### format date
52 |
53 | ```yml
54 | - name: Modify README.md
55 | uses: jaywcjlove/github-action-modify-file-content@main
56 | with:
57 | path: README.md
58 | body: "{{date:YYYY-MM-DD HH:mm:ss}}"
59 | ```
60 |
61 | ### overwrite file
62 |
63 | ```yml
64 | - name: Modify README.md
65 | uses: jaywcjlove/github-action-modify-file-content@main
66 | with:
67 | path: README.md
68 | body: "overwrite file content {{date:YYYY-MM-DD HH:mm:ss}}",
69 | overwrite: 'true'
70 | ```
71 |
72 | ### specify branch changes
73 |
74 | ```yml
75 | - name: Modify test test/overwrite.file.md
76 | uses: jaywcjlove/github-action-modify-file-content@main
77 | with:
78 | branch: test
79 | path: test/overwrite.file.md
80 | body: "{{date:YYYY-MM-DD HH:mm:ss}}"
81 | overwrite: 'true'
82 | ```
83 |
84 | ## See Also
85 |
86 | - [Github Release Changelog Generator](https://github.com/jaywcjlove/changelog-generator) A GitHub Action that compares the commit differences between two branches
87 | - [Create Tags From](https://github.com/jaywcjlove/create-tag-action) Auto create tags from commit or package.json.
88 | - [Github Action Contributors](https://github.com/jaywcjlove/github-action-contributors) Github action generates dynamic image URL for contributor list to display it!
89 | - [Generated Badges](https://github.com/jaywcjlove/generated-badges) Create a badge using GitHub Actions and GitHub Workflow CPU time (no 3rd parties servers)
90 | - [Create Coverage Badges](https://github.com/jaywcjlove/coverage-badges-cli) Create coverage badges from coverage reports. (no 3rd parties servers)
91 | - [Github Action package](https://github.com/jaywcjlove/github-action-package) Read and modify the contents of `package.json`.
92 | - [Github Action EJS](https://github.com/jaywcjlove/github-action-package) A github action to render a ejs template using github context.
93 | - [Github Action Read File Content](https://github.com/jaywcjlove/github-action-read-file)
94 | Read file contents. You can also get the file content in the branch.
95 |
96 | ## Contributors
97 |
98 | As always, thanks to our amazing contributors!
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | ## License
107 |
108 | Licensed under the MIT License.
109 |
--------------------------------------------------------------------------------
/action.yml:
--------------------------------------------------------------------------------
1 | name: 'Modify File Content'
2 | author: 'Kenny Wong'
3 | description: 'Replace text content and submit content'
4 | inputs:
5 | token:
6 | description: 'Your GITHUB_TOKEN'
7 | default: ${{ github.token }}
8 | required: false
9 | body:
10 | description: 'what needs to be replaced'
11 | default: ''
12 | required: true
13 | trim_whitespace:
14 | description: 'Optional. Whether leading/trailing whitespace will be trimmed for the body input. Defaults to true'
15 | default: true
16 | required: false
17 | path:
18 | description: 'File to be replaced'
19 | default: ''
20 | required: false
21 | ref:
22 | description: 'The name of the commit/branch/tag. Default: the repository’s default branch (usually `master`)'
23 | default: ''
24 | required: false
25 | branch:
26 | description: 'The person that committed the file. Default: the authenticated user.'
27 | default: ${{ github.ref_name }}
28 | required: false
29 | message:
30 | description: 'The commit message.'
31 | default: ''
32 | required: false
33 | committer_name:
34 | description: 'The name of the author or committer of the commit.'
35 | default: 'github-actions[bot]'
36 | required: false
37 | committer_email:
38 | description: 'The email of the author or committer of the commit.'
39 | default: 'github-actions[bot]@users.noreply.github.com'
40 | required: false
41 | openDelimiter:
42 | description: 'Character to use for opening delimiter, by default ``'
43 | default: ''
44 | required: false
45 | closeDelimiter:
46 | description: 'Character to use for closing delimiter, by default ``'
47 | default: ''
48 | required: false
49 | overwrite:
50 | description: 'overwrite file'
51 | default: 'false'
52 | required: false
53 | sync_local_file:
54 | description: 'Sync local file content'
55 | default: 'true'
56 | required: false
57 |
58 | outputs:
59 | content:
60 | description: 'text file content'
61 |
62 | runs:
63 | using: 'node20'
64 | main: 'dist/index.js'
65 |
66 | branding:
67 | icon: 'list'
68 | color: 'blue'
69 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "github-action-modify-file-content",
3 | "version": "2.0.4",
4 | "description": "Replace text content and submit content",
5 | "homepage": "https://github.com/jaywcjlove/github-action-modify-file-content#readme",
6 | "main": "dist/index.js",
7 | "scripts": {
8 | "prepare": "husky",
9 | "build": "ncc build src/index.ts -o dist",
10 | "watch": "ncc watch src/index.ts -o dist"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "https://github.com/jaywcjlove/github-action-modify-file-content.git"
15 | },
16 | "keywords": [],
17 | "author": "jaywcjlove",
18 | "license": "MIT",
19 | "engines": {
20 | "node": ">=v20.11.0",
21 | "npm": ">=10.2.4"
22 | },
23 | "dependencies": {
24 | "@actions/core": "~1.10.0",
25 | "@actions/github": "~6.0.0",
26 | "@uiw/formatter": "~2.0.1",
27 | "fs-extra": "~11.2.0"
28 | },
29 | "devDependencies": {
30 | "@kkt/ncc": "~1.1.1",
31 | "husky": "^9.0.11",
32 | "lint-staged": "^15.2.2"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:base"
5 | ],
6 | "packageRules": [
7 | {
8 | "matchPackagePatterns": ["*"],
9 | "rangeStrategy": "replace"
10 | }
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { getInput, getBooleanInput, startGroup, endGroup, setFailed, info, warning } from '@actions/core';
2 | import formatter from '@uiw/formatter';
3 | import { modifyPathContents } from './utils';
4 |
5 | const REGEXP = /\{\{date:?(.*?)\}\}/ig
6 |
7 | ;(async () => {
8 | const filepath = getInput('path') || '';
9 | try {
10 | let trimWhitespace = getBooleanInput('trim_whitespace');
11 | let body = getInput('body', { trimWhitespace }) || '';
12 | if (!body) {
13 | warning(`👉 [github-action-modify-file-content]: "body" input value does not exist.`)
14 | return
15 | }
16 | if (!filepath) {
17 | warning(`👉 [github-action-modify-file-content]: "path" input value does not exist.`)
18 | return
19 | }
20 | if (REGEXP.test(body)) {
21 | const result = body.replace(REGEXP, (match, str2) => {
22 | const format = match.replace(REGEXP, '$1');
23 | const str = formatter(format || 'YYYY/MM/DD HH:mm:ss', new Date());
24 | return str
25 | });
26 |
27 | if (result) {
28 | body = result
29 | }
30 | }
31 |
32 | startGroup(`👉 Body input content:`);
33 | info(body)
34 | endGroup();
35 |
36 | await modifyPathContents({ path: filepath }, body);
37 | } catch (error) {
38 | if (error instanceof Error) {
39 | setFailed(`${error.message} - ${filepath}`);
40 | }
41 | }
42 | })();
43 |
--------------------------------------------------------------------------------
/src/utils.ts:
--------------------------------------------------------------------------------
1 | import FS from 'fs-extra';
2 | import path from 'path';
3 | import { context, getOctokit } from '@actions/github';
4 | import { getInput, setOutput, startGroup, info, endGroup, warning } from '@actions/core';
5 | import { paths } from '@octokit/openapi-types';
6 | import { GetResponseTypeFromEndpointMethod } from '@octokit/types';
7 |
8 | export type FilePutQuery = paths['/repos/{owner}/{repo}/contents/{path}']['put']['requestBody']['content']['application/json'] & paths['/repos/{owner}/{repo}/contents/{path}']['put']['parameters']['path'];
9 | // export type FilePutResult = paths['/repos/{owner}/{repo}/contents/{path}']['get']['responses']['200']['content']['application/vnd.github.v3.object']
10 | // export type FilePutResultData = components['schemas']['content-file']
11 | type GetContentResponseType = GetResponseTypeFromEndpointMethod['data'];
12 |
13 |
14 | export const myToken = getInput('token');
15 | export const octokit = getOctokit(myToken);
16 |
17 | export const getInputs = () => {
18 | const body = getInput('body') || '';
19 | const ref = getInput('ref') || context.ref;
20 | const branch = getInput('branch');
21 | const sha = getInput('sha');
22 | const overwrite = getInput('overwrite') || 'false';
23 | const sync_local_file = getInput('sync_local_file') || 'true';
24 | const filepath = getInput('path') || '';
25 | const message = getInput('message') || '';
26 | const committer_name = getInput('committer_name') || '';
27 | const committer_email = getInput('committer_email') || '';
28 | const openDelimiter = getInput('openDelimiter') || '';
29 | const closeDelimiter = getInput('closeDelimiter') || '';
30 |
31 | return {
32 | ...context.repo,
33 | body, filepath, ref, branch, sha,
34 | message,
35 | committer_name,
36 | committer_email,
37 | openDelimiter,
38 | closeDelimiter,
39 | overwrite,
40 | sync_local_file
41 | }
42 | }
43 |
44 | async function getBranch(): Promise {
45 | const { branch } = getInputs()
46 | if (branch !== null) {
47 | return Promise.resolve(branch);
48 | }
49 | const { data } = await octokit.rest.repos.get(context.repo);
50 | return data.default_branch;
51 | }
52 |
53 | async function getFileContents(branch: string): Promise {
54 | const {owner, repo, filepath} = getInputs()
55 | try {
56 | const { data } = await octokit.rest.repos.getContent({
57 | owner, repo, ref: branch, path: filepath
58 | });
59 | return data;
60 | } catch (err) {
61 | warning(`👉 [github-action-modify-file-content]: Get File Contents: ${err instanceof Error ? err.message : err}`);
62 | return;
63 | }
64 | }
65 |
66 | function getBodyContent(oldFileContent: string, content: string) {
67 | const {openDelimiter, closeDelimiter, overwrite} = getInputs()
68 | const REG = new RegExp(`${openDelimiter}([\\s\\S]*?)${closeDelimiter}`, 'ig')
69 | const match = oldFileContent.match(REG);
70 | startGroup(`👉 Current File content: ${match?.length}`);
71 | info(`👉 ${JSON.stringify(match, null, 2)}`);
72 | endGroup();
73 | if (overwrite.toString() === 'true') {
74 |
75 | }
76 | return oldFileContent.replace(REG, `${openDelimiter}${content}${closeDelimiter}`)
77 | }
78 |
79 | export async function modifyPathContents(options: Partial = {}, content: string) {
80 | const { ...other} = options;
81 | const { owner, repo, message, committer_name, committer_email, overwrite, sync_local_file, ref} = getInputs();
82 | const branch = await getBranch();
83 | if (!options.path) {
84 | throw new Error(`modifyPathContents: file directory parameter does not exist`)
85 | }
86 | info(`👉 Modify Path (${options.path})`);
87 | info(`👉 Context.ref: (${context.ref})`);
88 | info(`👉 Context.sha: (${context.sha})`);
89 | info(`👉 branch: (${branch})`);
90 |
91 | let new_content = Buffer.from(content).toString("base64")
92 | let body: FilePutQuery = {
93 | owner, repo,
94 | path: options.path,
95 | branch,
96 | message: message || `doc: update ${options.path}.`,
97 | committer: {
98 | name: committer_name || 'github-actions[bot]',
99 | email: committer_email || 'github-actions[bot]@users.noreply.github.com'
100 | },
101 | ...other,
102 | content: new_content,
103 | }
104 | startGroup(`👉 Init Body: (${branch})`)
105 | info(`👉 ${JSON.stringify(body, null, 2)}`)
106 | endGroup()
107 | const currentFile = await getFileContents(branch);
108 | if (currentFile && 'content' in currentFile) {
109 | const fileContent = currentFile.content || '';
110 | const oldFileContent = Buffer.from(fileContent, 'base64').toString();
111 | let reuslt = getBodyContent(oldFileContent, content)
112 | startGroup(`👉 Current File content: ${options.path}`);
113 | info(`👉 ${JSON.stringify(currentFile, null, 2)}`);
114 | endGroup();
115 | if (overwrite.toString() === 'true') {
116 | body.content = new_content;
117 | reuslt = content;
118 | } else {
119 | body.content = Buffer.from(reuslt).toString("base64");
120 | new_content = reuslt;
121 | }
122 | setOutput('content', Buffer.from(body.content, 'base64').toString());
123 | startGroup(`👉 Text OLD content: ${oldFileContent == reuslt}`);
124 | info(`👉 ${oldFileContent}`);
125 | endGroup();
126 | startGroup(`👉 Text NEW content: ${oldFileContent == reuslt}`);
127 | info(`👉 ${reuslt}`);
128 | endGroup();
129 | if (oldFileContent == reuslt) {
130 | warning(`👉 [github-action-modify-file-content]: Content has not changed!!!!!`)
131 | return;
132 | }
133 | body = { ...body, ...currentFile, content: body.content, sha: currentFile.sha }
134 | const fullPath = path.resolve(options.path);
135 | const isExists = FS.existsSync(fullPath);
136 | if (isExists && sync_local_file.toString() === 'true' && ref === context.ref) {
137 | await FS.writeFile(fullPath, new_content);
138 | }
139 | startGroup(`modifyPathContents Body:`)
140 | info(`👉 ${JSON.stringify(body, null, 2)}`)
141 | endGroup()
142 | const result = await octokit.request('PUT /repos/{owner}/{repo}/contents/{path}', {
143 | ...body,
144 | sha: currentFile.sha
145 | });
146 | startGroup(`file result:`)
147 | info(`👉 ${result.data.content?.path}`)
148 | info(`👉 ${result.data.content?.size}`)
149 | info(`👉 ${result.data.content?.sha}`)
150 | endGroup()
151 | } else {
152 | warning(`👉 [github-action-modify-file-content]: Not Found ::- ${options.path}`)
153 | const result = await octokit.request('PUT /repos/{owner}/{repo}/contents/{path}', {
154 | ...body,
155 | });
156 | startGroup(`file result:`)
157 | info(`👉 ${result.data.content?.path}`)
158 | info(`👉 ${result.data.content?.size}`)
159 | info(`👉 ${result.data.content?.sha}`)
160 | endGroup()
161 | }
162 | }
--------------------------------------------------------------------------------
/test/overwrite.file.md:
--------------------------------------------------------------------------------
1 | 2025-05-12 17:15:57
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2015",
4 | "module": "commonjs",
5 | "outDir": "./lib",
6 | "rootDir": "./src",
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "declaration": true,
10 | "noEmit": true,
11 | "esModuleInterop": true,
12 | "moduleResolution": "node",
13 | },
14 | "include": [
15 | "src/**/*.ts",
16 | ],
17 | "exclude": [
18 | "node_modules"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------