Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ jobs:
- name: Run tests
run: npm test

- name: Upload test artifacts
if: github.event_name == 'pull_request' && github.event.pull_request.draft == false
uses: actions/upload-artifact@v4
with:
name: plugin-build-${{ github.event.pull_request.number }}
path: |
main.js
manifest.json
styles.css
retention-days: 14

# ------------------------------------------------------------------
# Release — only on push to main/master, after build passes.
# Analyses conventional commits since the last tag, bumps the
Expand Down
52 changes: 51 additions & 1 deletion main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -593,13 +593,63 @@ export default class GitHubOctokitPlugin extends Plugin {
void _ignored; // intentionally unused - just extracting syncState from data
void _ignored2;
this.settings = Object.assign({}, DEFAULT_SETTINGS, settingsData);

// Migrate main token from plaintext data.json to SecretStorage
const storedSecret = this.app.secretStorage.getSecret('github-pat');
if (storedSecret) {
// Token already in SecretStorage — use it
this.settings.auth.token = storedSecret;
} else if (this.settings.auth.token) {
// Legacy: token still in data.json — migrate to SecretStorage
this.app.secretStorage.setSecret('github-pat', this.settings.auth.token);
}

// Migrate additional repo tokens to SecretStorage
let needsSave = false;
for (const repo of this.settings.additionalRepos) {
if (repo.useMainToken) continue;
const secretKey = `github-pat-${repo.id}`;
const repoSecret = this.app.secretStorage.getSecret(secretKey);
if (repoSecret) {
repo.token = repoSecret;
} else if (repo.token) {
this.app.secretStorage.setSecret(secretKey, repo.token);
needsSave = true;
}
}

// Clear legacy tokens from data.json if any were migrated
if (needsSave || (!storedSecret && this.settings.auth.token)) {
await this.saveSettings();
}
}

async saveSettings() {
// Preserve syncState when saving settings
const data = (await this.loadData() || {}) as PersistedPluginData;
await this.saveData({

// Persist main token to SecretStorage
if (this.settings.auth.token) {
this.app.secretStorage.setSecret('github-pat', this.settings.auth.token);
}

// Persist additional repo tokens to SecretStorage
const cleanedRepos = this.settings.additionalRepos.map(repo => {
if (!repo.useMainToken && repo.token) {
this.app.secretStorage.setSecret(`github-pat-${repo.id}`, repo.token);
}
return { ...repo, token: '' };
});

// Exclude all tokens from persisted settings
const settingsToSave = {
...this.settings,
auth: { ...this.settings.auth, token: '' },
additionalRepos: cleanedRepos,
};

await this.saveData({
...settingsToSave,
syncState: data.syncState,
additionalRepoStates: data.additionalRepoStates,
});
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"id": "github-octokit",
"name": "GitHub Octokit Sync",
"version": "0.4.1",
"minAppVersion": "1.7.2",
"minAppVersion": "1.12.7",
"description": "Sync your vault with GitHub using the Octokit API.",
"author": "M Rhoades-Brown",
"authorUrl": "https://github.com/rhoades-brown",
Expand Down
25 changes: 25 additions & 0 deletions src/views/SyncView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,29 @@ export class SyncView extends ItemView {
constructor(leaf: WorkspaceLeaf, plugin: GitHubOctokitPlugin) {
super(leaf);
this.plugin = plugin;
this.loadViewState();
}

/** Restore persisted UI state from vault-specific localStorage */
private loadViewState(): void {
const state = this.plugin.app.loadLocalStorage('github-octokit-sync-view') as string | null;
if (state) {
try {
const parsed = JSON.parse(state) as { commitsExpanded?: boolean; logsExpanded?: boolean };
if (typeof parsed.commitsExpanded === 'boolean') this.commitsExpanded = parsed.commitsExpanded;
if (typeof parsed.logsExpanded === 'boolean') this.logsExpanded = parsed.logsExpanded;
} catch {
// Ignore corrupt state
}
}
}

/** Persist UI state to vault-specific localStorage */
private saveViewState(): void {
this.plugin.app.saveLocalStorage('github-octokit-sync-view', JSON.stringify({
commitsExpanded: this.commitsExpanded,
logsExpanded: this.logsExpanded,
}));
}

getViewType(): string {
Expand Down Expand Up @@ -412,6 +435,7 @@ export class SyncView extends ItemView {

header.addEventListener('click', () => {
this.commitsExpanded = !this.commitsExpanded;
this.saveViewState();
void this.render();
});

Expand Down Expand Up @@ -476,6 +500,7 @@ export class SyncView extends ItemView {
// Don't toggle if clicking on controls
if ((e.target as HTMLElement).closest('.logs-controls')) return;
this.logsExpanded = !this.logsExpanded;
this.saveViewState();
void this.render();
});

Expand Down
13 changes: 13 additions & 0 deletions tests/mocks/obsidian.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
// Mock Obsidian module for testing

export class SecretStorage {
private secrets: Map<string, string> = new Map();
setSecret(id: string, secret: string): void { this.secrets.set(id, secret); }
getSecret(id: string): string | null { return this.secrets.get(id) ?? null; }
listSecrets(): string[] { return Array.from(this.secrets.keys()); }
}

export class App {
vault = new Vault();
workspace = new Workspace();
secretStorage = new SecretStorage();
private localStorage: Map<string, string> = new Map();
loadLocalStorage(key: string): string | null { return this.localStorage.get(key) ?? null; }
saveLocalStorage(key: string, data: unknown | null): void {
if (data === null) { this.localStorage.delete(key); } else { this.localStorage.set(key, String(data)); }
}
}

export class Vault {
Expand Down
3 changes: 2 additions & 1 deletion versions.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"0.1.0": "0.15.0",
"0.3.2": "1.7.2",
"0.4.1": "1.7.2"
"0.4.1": "1.7.2",
"0.5.0": "1.12.7"
}
Loading