Skip to content

Commit

Permalink
Modularize source files (#12)
Browse files Browse the repository at this point in the history
* build: update dependencies

* build: add eslint

* build: update dependencies

* build: Move Typescript declaration into dependencies

* build: update package.json

* chore: add paths into gitignore

* chore: add eslintrc.cjs

* build: update tsconfig.json

* feat: modularize source files

* fix: delete unexpected value

* fix: delete lines

* fix: update repo and username pattern accepted by GitHub

* fix: update git repo path

* fix: update minimum number of LatestWorkflowRunTime

* fix: selecting wrong array index

* fix: fatal error during searching git latest

* fix: add some debugging info

* chore: add some debugging info

* fix: actions/checkout does not clone all history

* fix: check if the cache is up to date

* fix: return the previous commit

* docs: update README

* fix: when a workflow run is triggered in non-default branch
  • Loading branch information
piquark6046 authored Nov 21, 2023
1 parent bffbf65 commit 649dd65
Show file tree
Hide file tree
Showing 17 changed files with 621 additions and 187 deletions.
40 changes: 40 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module.exports = {
env: {
es2022: true
},
extends: [
'xo'
],
overrides: [
{
extends: [
'xo-typescript',
],
files: [
'calc-repo-size/**/*.ts',
'sources/**/*.ts',
'index.ts'
],
rules:
{
'@typescript-eslint/naming-convention': ['error', {
selector: ['variableLike', 'parameterProperty', 'classProperty', 'typeProperty'],
format: ['PascalCase']
}],
'@typescript-eslint/semi': ['error', 'never'],
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'new-cap': 'off'
}
}
],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module'
},
rules: {
'no-var': 'off',
'comma-dangle': 'off',
indent: ['off', 'tab'],
semi: 'off'
}
}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
node_modules
.env
.env
dist
.vscode/launch.json
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ If you want to purge jsDelivr cache automatically, please customize the followin
```
name: 'Run jsDelivr-Purge'
on:
schedule:
- cron: '* 0/1 * * *'
workflow_dispatch:
permissions:
actions: read
contents: read
Expand All @@ -21,8 +16,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Run jsDelivr-Purge
uses: List-KR/jsdelivr-purge@v4
uses: List-KR/jsdelivr-purge@5.0.0
```

The jsDelivr-Purge supports `workflow_dispatch`, `schedule` and `push` event.

It always purges `latest` and the default branch of your repo.

> **Warning**: jsDelivr will add authentication data into a request header.
You need to pay attention to this change!
50 changes: 28 additions & 22 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,48 @@ inputs:
branches:
description: 'The your branches that you want to purge cache existing in jsDelivr'
required: false
default: 'master main'

delay:
description: 'A time that delay between GitHub RAW file service and actual git operation'
required: false
default: '2:0:0'
default: 'latest'

runs:
using: 'composite'
steps:
- name: Set up NodeJS LTS
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- name: Install npm packages
run: |
sudo npm i -g npm
sudo npm i -g typescript
sudo npm update -g npm
sudo npm update -g typescript
npm i
shell: bash
working-directory: ${{ github.action_path }}
- name: Compile Typescript
run: tsc
shell: bash
working-directory: ${{ github.action_path }}
- name: Create env file
- name: Check if size of the repo exceeds the runner's hardware capacity
id: check_size
env:
GITHUB_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
CI_WORKSPACE_PATH: ${{ github.workspace }}
run: |
touch .env
echo GITHUB_REPO=${{ github.repository }} >> .env
echo GITHUB_TOKEN=${{ github.token }} >> .env
echo GITHUB_WORKFLOW_REF=${{ github.workflow_ref }} >> .env
echo INPUT_BRANCHES=${{ inputs.branches }} >> .env
echo INPUT_DELAY=${{ inputs.delay }} >> .env
npm run calc-repo-size -- --gh-token "$GITHUB_TOKEN" --repo "$REPO" --ci-workspace-path "$CI_WORKSPACE_PATH"
shell: bash
working-directory: ${{ github.action_path }}
- name: Run compiled scripts
run: node main.js
- name: Clone repo into github.workspace
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.repository.default_branch }}
if: ${{ steps.check_size.outputs.should_api != 'true' }}
- name: Run program
env:
GITHUB_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
BRANCHE: ${{ inputs.branches }}
WORKFLOWREF: ${{ github.workflow_ref }}
CI_WORKSPACE_PATH: ${{ github.workspace }}
CI_ACTION_PATH: ${{ github.action_path }}
SHOULD_USE_API: ${{ steps.check_size.outputs.should_use_api }}
run: |
npm run ci -- --gh-token "$GITHUB_TOKEN" --repo "$REPO" --workflow-ref "$WORKFLOWREF" --branch "$BRANCHE" --ci-workspace-path "$CI_WORKSPACE_PATH" --ci-action-path "$CI_ACTION_PATH" --should-use-api "$SHOULD_USE_API"
shell: bash
working-directory: ${{ github.action_path }}
39 changes: 39 additions & 0 deletions calc-repo-size/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as GitHub from '@octokit/rest'
import * as Actions from '@actions/core'
import * as Commander from 'commander'
import checkDiskSpace from 'check-disk-space'

const Program = new Commander.Command()

Program.option('--debug', 'output extra debugging', false)
.option('--gh-token <TOKEN>', 'GitHub token', '')
.option('--repo <REPO>', 'A GitHub repository. eg: owner/repo', '')
.option('--ci-workspace-path <PATH>', 'A path to the CI workspace.', '')

Program.parse()

type ProgramOptionsType = {
// eslint-disable-next-line @typescript-eslint/naming-convention
debug: boolean;
// eslint-disable-next-line @typescript-eslint/naming-convention
ghToken: string;
// eslint-disable-next-line @typescript-eslint/naming-convention
repo: string;
// eslint-disable-next-line @typescript-eslint/naming-convention
ciWorkspacePath: string;
}
const ProgramOptions: ProgramOptionsType = Program.opts()

const GitHubInstance = new GitHub.Octokit({auth: ProgramOptions.ghToken})
const RepoSize = GitHubInstance.repos.get({owner: ProgramOptions.repo.split('/')[0], repo: ProgramOptions.repo.split('/')[1]})
.then(Response => Response.data.size)
const DiskFreeSize = checkDiskSpace(ProgramOptions.ciWorkspacePath).then(DiskInfo => DiskInfo.free)

await Promise.all([RepoSize, DiskFreeSize]).then(([RepoSizeVaule, DiskFreeSizeVaule]) => {
Actions.info(`calc-repo-size: RepoSize: ${RepoSizeVaule}; DiskFreeSize: ${DiskFreeSizeVaule}`)
if (RepoSizeVaule * 1000 < DiskFreeSizeVaule) {
Actions.setOutput('should_use_api', 'false')
} else {
Actions.setOutput('should_use_api', 'true')
}
})
50 changes: 50 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import * as Commander from 'commander'
import type * as Types from './sources/types'
import {ExportArgs, IsDebug} from './sources/debug'
import {ReplaceStringWithBooleanInObject} from './sources/utility'
import {GetLatestWorkflowTime} from './sources/actions'
import {ListBranches} from './sources/branches'
import {GetChangedFilesFromSHAToHead, GetCommitSHAFromLatestWorkflowTime} from './sources/commits'
import {PurgeRequestManager} from './sources/requests'

const Program = new Commander.Command()

// Set options.
Program.option('--debug', 'output extra debugging', false)
.option('--gh-token <TOKEN>', 'GitHub token', '')
.option('--repo <REPO>', 'A GitHub repository. eg: owner/repo', '')
.option('--workflow-ref <WORKFLOW_REF>', 'A GitHub workflow ref. eg: refs/heads/master', '')
.option('--branch <BRANCH>', 'A GitHub branch. eg: master', '')
.option('--ci-workspace-path <PATH>', 'A path to the CI workspace.', '')
.option('--ci-action-path <PATH>', 'A path to the CI action.', '')
.option('--should-use-api <TRUE_OR_FALSE>', 'Should use GitHub API?', 'false')

// Initialize Input of the options and export them.
Program.parse()

// Declare the options and print them if the debugging mode is enabled.
const ProgramRawOptions: Types.ProgramOptionsRawType = Program.opts()
if (IsDebug(ProgramRawOptions)) {
ExportArgs(ProgramRawOptions)
}

// Redefine with boolean.
const ProgramOptions = ReplaceStringWithBooleanInObject(ProgramRawOptions) as Types.ProgramOptionsType

// Workflow
const LatestWorkflowRunTime = await GetLatestWorkflowTime(ProgramOptions).then(LatestWorkflowRunTime => LatestWorkflowRunTime)
const Branches = await ListBranches(ProgramOptions).then(Branches => Branches)
const PurgeRequest = new PurgeRequestManager(ProgramOptions)
for (const Branch of Branches) {
// eslint-disable-next-line no-await-in-loop
const CommitSHA = await GetCommitSHAFromLatestWorkflowTime(ProgramOptions, LatestWorkflowRunTime, Branch).then(CommitSHA => CommitSHA)
if (CommitSHA === null) {
continue
}

// eslint-disable-next-line no-await-in-loop
const ChangedFiles = await GetChangedFilesFromSHAToHead(ProgramOptions, CommitSHA, Branch, Branches[1]).then(ChangedFiles => ChangedFiles)
PurgeRequest.AddURLs(ChangedFiles, Branch)
}

PurgeRequest.Start()
52 changes: 0 additions & 52 deletions main.ts

This file was deleted.

35 changes: 32 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,44 @@
{
"name": "jsdelivr-purge",
"version": "5.0.0",
"author": {
"name": "PiQuark6046",
"email": "piquark6046@proton.me",
"url": "https://github.com/piquark6046"
},
"repository": {
"type": "git",
"url": "https://github.com/List-KR/jsdelivr-purge"
},
"bugs": {
"url": "https://github.com/List-KR/jsdelivr-purge/issues"
},
"homepage": "https://github.com/List-KR/jsdelivr-purge",
"license": "MIT",
"type": "module",
"scripts": {
"ci": "tsx index.ts",
"calc-repo-size": "tsx calc-repo-size/index.ts"
},
"dependencies": {
"@actions/core": "^1.10.0",
"@octokit/rest": "^20.0.1",
"@types/luxon": "^3.2.0",
"dotenv": "^16.0.3",
"@types/luxon": "^3.3.3",
"@types/node": "^20.8.10",
"check-disk-space": "^3.4.0",
"commander": "^11.1.0",
"got": "^12.6.1",
"luxon": "^3.3.0",
"p-queue": "^7.4.1",
"simple-git": "^3.20.0",
"tsx": "^3.14.0",
"typescript": "^5.0.2"
},
"devDependencies": {
"@types/node": "^20.1.0"
"@typescript-eslint/eslint-plugin": "^6.9.1",
"@typescript-eslint/parser": "^6.9.1",
"eslint": "^8.52.0",
"eslint-config-xo": "^0.43.1",
"eslint-config-xo-typescript": "^1.0.1"
}
}
27 changes: 27 additions & 0 deletions sources/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as GitHub from '@octokit/rest'
import {DateTime} from 'luxon'
import type {ProgramOptionsType} from './types'

/**
* @name GetLatestWorkflowTime
* @description Get the latest workflow time.
* @param {ProgramOptionsType} ProgramOptions The program options.
* @returns {Promise<number>} The latest workflow time in milliseconds.
*/
export async function GetLatestWorkflowTime(ProgramOptions: ProgramOptionsType): Promise<number> {
const GitHubInstance = new GitHub.Octokit({auth: ProgramOptions.ghToken})
const [RepoOwner, RepoName] = ProgramOptions.repo.split('/')
var LatestWorkflowRunTime = 0
const WorkflowRuns = await GitHubInstance.actions.listWorkflowRuns({
owner: RepoOwner, repo: RepoName,
workflow_id: /(?<=^[A-z0-9-_]+\/[A-z0-9-_]+\/\.github\/workflows\/).+\.yml(?=@refs\/)/.exec(ProgramOptions.workflowRef)[0],
}).then(WorkflowRuns => WorkflowRuns.data.workflow_runs)
for (const WorkflowRun of WorkflowRuns) {
if (WorkflowRun.status === 'completed' && WorkflowRun.conclusion === 'success'
&& DateTime.fromISO(WorkflowRun.updated_at).toMillis() > LatestWorkflowRunTime) {
LatestWorkflowRunTime = DateTime.fromISO(WorkflowRun.updated_at).toMillis()
}
}

return LatestWorkflowRunTime
}
Loading

0 comments on commit 649dd65

Please sign in to comment.