Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
411732b
PT-1886: Set up theme contributions, fixed raw file imports not worki…
tjcouch-sil Apr 29, 2025
c669517
Added section to README about renaming an extension
tombogle May 29, 2025
4897b41
PT-2390: Added section to README about renaming an extension (#49)
tombogle May 29, 2025
fa9200d
Pinned swc/core to version 1.10.18 to help keep all extensions on the…
tombogle Jun 3, 2025
bac8505
Pinned swc/core to version 1.10.18 (#50)
tombogle Jun 3, 2025
9c1c5ce
Add codeql.yml to run CodeQL manually (#51)
tjcouch-sil Jun 11, 2025
32f7916
Remove the need for placeholder editing after calling create-extensio…
jasonleenaylor Jun 11, 2025
7370108
Add "remote-allow-origins" to launch.json to allow external debugging…
lyonsil Jun 11, 2025
31034e5
Add github action for CI (lint, check format, build) (#53)
jasonleenaylor Jun 11, 2025
4c784ab
Add CI for release-prep and hotfix branches and run format first (#54)
jasonleenaylor Jun 12, 2025
b3b597c
Add a guard against empty extension names with error log (#55)
jasonleenaylor Jun 13, 2025
79e4bca
Merge remote-tracking branch 'paranext-multi-extension-template/main'
lyonsil Jun 13, 2025
f031a34
Squashed 'src/scripture-forge/' changes from a79494c..8d302c8
lyonsil Jun 13, 2025
1e12c82
Merge commit 'f031a34a277e1e3758c0d0060b2217bed187396b' into update-f…
lyonsil Jun 13, 2025
9f92952
Update package-lock.json and fix prettier problems
lyonsil Jun 13, 2025
2522bbb
Update lint script
lyonsil Jun 13, 2025
819696a
stop formatting package.json
lyonsil Jun 13, 2025
fbe6870
update the right workflow file!
lyonsil Jun 13, 2025
a7f4816
keep trying
lyonsil Jun 13, 2025
3daca61
keep going
lyonsil Jun 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
* text eol=lf
*.exe binary
*.png binary
*.jpg binary
*.jpeg binary
*.ico binary
*.icns binary
*.eot binary
*.otf binary
*.ttf binary
*.woff binary
*.woff2 binary
*.ldml binary
*.zip binary
88 changes: 88 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: 'CodeQL'

on:
push:
branches: ['main', 'release-prep', 'hotfix-*']
pull_request:
branches: ['main', 'release-prep', 'hotfix-*']
workflow_dispatch:

jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write

# required to fetch internal or private CodeQL packs
packages: read

# only required for workflows in private repositories
actions: read
contents: read

strategy:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
- language: javascript-typescript
build-mode: none
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v4

# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
# or others). This is typically only required for manual builds.
# - name: Setup runtime (example)
# uses: actions/setup-example@v1

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.

# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality

# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- if: matrix.build-mode == 'manual'
shell: bash
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 1

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: '/language:${{matrix.language}}'
53 changes: 53 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Lint

on:
push:
branches: ['main', 'release-prep', 'hotfix-*']
pull_request:
branches: ['main', 'release-prep', 'hotfix-*']

permissions:
contents: read

jobs:
lint:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
steps:
- name: Checkout git repo
uses: actions/checkout@v4
with:
path: extension-repo

- name: Checkout paranext-core repo to use its sub-packages
uses: actions/checkout@v4
with:
path: paranext-core
repository: paranext/paranext-core

- name: Setup Node.js
uses: actions/setup-node@v4
with:
cache: 'npm'
cache-dependency-path: |
extension-repo/package-lock.json
paranext-core/package-lock.json
node-version-file: extension-repo/package.json

- name: Install extension dependencies
working-directory: extension-repo
run: npm ci

- name: Install core dependencies
working-directory: paranext-core
run: npm ci --ignore-scripts

- name: Run format checking
working-directory: extension-repo
run: npm run format:check

- name: Run all linters
working-directory: extension-repo
run: npm run lint
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ temp-build

# generated files
package-lock.json
package.json

# #endregion
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"runtimeArgs": ["run", "start"],
"skipFiles": ["<node_internals>/**"],
"env": {
"MAIN_ARGS": "--inspect=5858 --remote-debugging-port=9223",
"MAIN_ARGS": "--inspect=5858 --remote-debugging-port=9223 --remote-allow-origins=http://localhost:9223",
"IN_VSCODE": "true"
},
"presentation": {
Expand Down
50 changes: 38 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ This is a Webpack project configured to build Platform.Bible extensions. The gen

## To install

### Install dependencies:
### Install dependencies

1. Follow the instructions to install [`paranext-core`](https://github.com/paranext/paranext-core#developer-install). We recommend you clone `paranext-core` in the same parent directory in which you cloned this repository so you do not have to [reconfigure paths](#configure-paths-to-paranext-core-repo) to `paranext-core`.
2. In this repo, run `npm install` to install local and published dependencies
Expand Down Expand Up @@ -155,16 +155,16 @@ These steps will walk you through releasing a version on GitHub and bumping the
<details>
<summary>[Optional] Create a new pre-release and bump versions branch manually </summary>

#### Manually create a new pre-release and bump versions branch
### Manually create a new pre-release and bump versions branch

Alternatively, you can create a new pre-release manually:

```bash
npm run package
# Create a new pre-release in GitHub on tag `v<version>`
# Copy `.github/assets/release-body.md` into the GitHub branch
# Generate changelog
# Attach contents of `release` folder
# Copy `.github/assets/release-body.md` into the release body
# Press the "Generate release notes" button in the release creation page to generate a changelog
# Attach contents of `release` folder to the release
```

Then bump versions by running the following:
Expand Down Expand Up @@ -197,12 +197,12 @@ Following are some problems you may encounter while publishing and steps to solv

If you see the following error in the GitHub Actions workflow logs while packaging:

```
```bash
Module build failed (from ./node_modules/swc-loader/src/index.js):
Error: Failed to load native binding
```

You may have a different effective version of `@swc/core` than `paranext-core` does. Please make sure the version of `@swc/core` in your `package-lock.json` is the same as its version in [`paranext-core/package-lock.json`](https://github.com/paranext/paranext-core/blob/main/package-lock.json). If they are not the same, please fix them to be the same by running `npm i -D @swc/core <version>` where the version is the version of `@swc/core` installed in `paranext-core/package-lock.json` (if you would like to set the version of `@swc/core` back to what it was before in `package.json` to stay synced with the extension template, change it back manually in `package.json` and then run `npm i`). If they are already the same, you may need to try regenerating your `package-lock.json` file by deleting it and running `npm i`.
You may have a different effective version of `@swc/core` than `paranext-core` does. Please make sure the version of `@swc/core` in your `package-lock.json` is the same as its version in [`paranext-core/package-lock.json`](https://github.com/paranext/paranext-core/blob/main/package-lock.json). If they are not the same, please fix them to be the same by running `npm i -D @swc/core@<version>` where the version is the version of `@swc/core` installed in `paranext-core/package-lock.json` (if you would like to set the version of `@swc/core` back to what it was before in `package.json` to stay synced with the extension template, change it back manually in `package.json` and then run `npm i`). If they are already the same, you may need to try regenerating your `package-lock.json` file by deleting it and running `npm i`.

## To create a new extension in this repo

Expand All @@ -214,15 +214,16 @@ npm run create-extension -- <extension-name>

Then follow [the instructions for customizing the new extension](https://github.com/paranext/paranext-extension-template#customize-extension-details) with a few modifications:

- Follow the instructions for replacing placeholders inside the `src/<extension-name>` folder, not at this repo root, except in specific situations:
- Instead of editing the `.github/assets/release-body.md` inside the extension, add information about the new extension in `.github/assets/release-body.md` at this repo root.
- All of the places where it says to replace the extension name in [Replace Placeholders](https://github.com/paranext/paranext-extension-template#replace-placeholders) have been automated,
the other instructions there should apply inside the `src/<extension-name>` folder, not at this repo root.
- Instead of editing the `.github/assets/release-body.md` inside the extension, add information about the new extension in `.github/assets/release-body.md` at this repo root.

**Note:** The merge/squash commits created when creating a new extension are important; Git uses them to compare the files for future updates. If you edit this repo's Git history, please preserve these commits (do not squash them, for example) to avoid duplicated merge conflicts in the future.

<details>
<summary>[Optional] Creating a new extension manually</summary>

#### Manually create a new extension
### Manually create a new extension

Alternatively, you can create a new extension manually:

Expand All @@ -238,11 +239,36 @@ the file paths pointing to `paranext-core`:
- Find: `([^/])\.\.\/paranext-core`
- Replace with: `$1../../../paranext-core`

You can ignore occurrences from many files. Please see [`./lib/git.util.ts`](./lib/git.util.ts) -> `formatExtensionFolder` for more
information.
You can ignore occurrences from many files. Please see [`./lib/git.util.ts`](./lib/git.util.ts) -> `formatExtensionFolder` for more information.

Because these steps are not automated you need to follow all the instructions in [Replace Placeholders](https://github.com/paranext/paranext-extension-template#replace-placeholders)

</details>

### Renaming an extension

Renaming an extension involves more than just changing its folder name. Tools that track extension updates rely on the folder name to detect changes, so renaming must be done carefully to avoid duplicated diffs or future merge conflicts.

**Note:** Unfortunately, this process effectively erases the history on all the files in this extension since they are being deleted and created anew from the perspective of the Git history.

To safely rename an extension:

1. [Update from the template](#to-update-this-repo-and-extensions-from-the-templates) to ensure the extension to be renamed has all latest changes (makes sure you don't revert any updates the template has received since you last updated the extension when you are copying the contents of the extension)

2. Run the [`create-extension` script](#to-create-a-new-extension-in-this-repo) with the new name to create a new folder:
```bash
npm run create-extension -- <new-extension-name>
```
3. Move the contents of the old extension into the new folder and delete the old folder. (If it's not already under source control, it would probably be wise to make a backup until you have confirmed that the rename was successful.)

4. Update internal identifiers and references to match the new name (e.g., folder names, class names, package names, strings inside files).

5. Test and commit the changes.

This process ensures that template update comparisons continue to work correctly.

**Note:** The merge/squash commits created when renaming an extension are important; Git uses them to compare the files for future updates. If you edit this repo's Git history, please preserve these commits (do not squash them, for example) to avoid duplicated merge conflicts in the future.

## To update this repo and extensions from the templates

This project is forked from [`paranext-multi-extension-template`](https://github.com/paranext/paranext-multi-extension-template), and its extensions are derived from [`paranext-extension-template`](https://github.com/paranext/paranext-extension-template). Both are updated periodically and will sometimes receive updates that help with breaking changes on [`paranext-core`](https://github.com/paranext/paranext-core). We recommend you periodically update your repo and extensions by merging the latest template updates into them.
Expand Down
8 changes: 7 additions & 1 deletion lib/create-extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ import { getExtensionPath } from '../webpack/webpack.util';
const newExtensionName = process.argv[2];

(async () => {
// verify that an extension name was provided
if (!newExtensionName) {
console.error(`No extension name provided.`);
return 1;
}

// Make sure there are not working changes as this will not work with working changes
if (await checkForWorkingChanges()) return 1;

Expand Down Expand Up @@ -43,7 +49,7 @@ const newExtensionName = process.argv[2];
// Don't commit for them so they know what is going on
if (await checkForWorkingChanges(true))
console.log(
`After creating the extension at ${extensionPathOSIndependent} from ${SINGLE_TEMPLATE_NAME} and formatting it, there are working changes.\nThis is likely expected. Please commit the result.`,
`After creating the extension at ${extensionPathOSIndependent} from ${SINGLE_TEMPLATE_NAME} and formatting it, there are working changes.\nThis is expected. Please commit the result.`,
);

return 0;
Expand Down
Loading