diff --git a/README.md b/README.md index 7a6e885..4b1b361 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,25 @@ This is a Github Action that can be used to publish [snap packages](https://snapcraft.io) to the Snap Store. In most cases, it will be used with the `snapcraft-build-action` action to build the -package. The following workflow should be sufficient for: +package. The following workflow should be sufficient for Snapcraft 7 or later: +```yaml +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: snapcore/action-build@v1 + id: build + - uses: snapcore/action-publish@v1 + env: + SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.STORE_LOGIN }} + with: + snap: ${{ steps.build.outputs.snap }} + release: edge +``` + +Alternatively, on Snapcraft 6 and older: ```yaml jobs: build: diff --git a/__tests__/publish.test.ts b/__tests__/publish.test.ts index 3bdd486..25c3d5e 100644 --- a/__tests__/publish.test.ts +++ b/__tests__/publish.test.ts @@ -168,3 +168,72 @@ test('SnapcraftPublisher.publish can release the published snap', async () => { ]) expect(execMock).toHaveBeenCalledWith('snapcraft', ['logout']) }) + +describe('process.env', () => { + const env = process.env + + beforeEach(() => { + jest.resetModules() + process.env = {...env} + }) + + afterEach(() => { + process.env = env + }) + + test('SnapcraftPublisher.publish can release the published snap with new login', async () => { + expect.assertions(5) + + const ensureSnapd = jest + .spyOn(tools, 'ensureSnapd') + .mockImplementation(async (): Promise => {}) + const ensureSnapcraft = jest + .spyOn(tools, 'ensureSnapcraft') + .mockImplementation(async (): Promise => {}) + const execMock = jest + .spyOn(exec, 'exec') + .mockImplementation( + async (program: string, args?: string[]): Promise => { + return 0 + } + ) + + process.env.SNAPCRAFT_STORE_CREDENTIALS = 'credentials' + const publisher = new publish.SnapcraftPublisher({ + loginData: '', + snapFile: 'filename.snap', + release: 'edge' + }) + await publisher.publish() + + expect(ensureSnapd).toHaveBeenCalled() + expect(ensureSnapcraft).toHaveBeenCalled() + expect(execMock).not.toHaveBeenCalledWith('snapcraft', [ + 'login', + '--with', + expect.any(String) + ]) + expect(execMock).toHaveBeenCalledWith('snapcraft', [ + 'upload', + 'filename.snap', + '--release', + 'edge' + ]) + expect(execMock).not.toHaveBeenCalledWith('snapcraft', ['logout']) + }) + + test('SnapcraftPublisher.validate validates inputs with new login', async () => { + expect.assertions(0) + + const existingSnap = path.join(__dirname, '..', 'README.md') + process.env.SNAPCRAFT_STORE_CREDENTIALS = 'credentials' + + // Missing login data but env set + let publisher = new publish.SnapcraftPublisher({ + loginData: '', + snapFile: existingSnap, + release: '' + }) + await publisher.validate() + }) +}) diff --git a/action.yml b/action.yml index 38aa4d5..90474e2 100644 --- a/action.yml +++ b/action.yml @@ -7,7 +7,7 @@ branding: inputs: store_login: description: 'The login data for the Snap Store produced with "snapcraft export-login"' - required: true + required: false snap: description: 'The snap file to upload to the store' required: true diff --git a/dist/index.js b/dist/index.js index 97f509c..d111ce5 100644 --- a/dist/index.js +++ b/dist/index.js @@ -3042,6 +3042,9 @@ class SnapcraftPublisher { this.release = options.release; } async validate() { + if (process.env.SNAPCRAFT_STORE_CREDENTIALS) { + return; + } if (!this.loginData) { throw new Error('login_data is empty'); } @@ -3077,12 +3080,16 @@ class SnapcraftPublisher { async publish() { await ensureSnapd(); await ensureSnapcraft(); - await this.login(); + if (!process.env.SNAPCRAFT_STORE_CREDENTIALS) { + await this.login(); + } try { await this.upload(); } finally { - await this.logout(); + if (!process.env.SNAPCRAFT_STORE_CREDENTIALS) { + await this.logout(); + } } } } diff --git a/src/publish.ts b/src/publish.ts index 71a9794..d508012 100644 --- a/src/publish.ts +++ b/src/publish.ts @@ -24,6 +24,10 @@ export class SnapcraftPublisher { } async validate(): Promise { + if (process.env.SNAPCRAFT_STORE_CREDENTIALS) { + return + } + if (!this.loginData) { throw new Error('login_data is empty') } @@ -63,11 +67,15 @@ export class SnapcraftPublisher { async publish(): Promise { await tools.ensureSnapd() await tools.ensureSnapcraft() - await this.login() + if (!process.env.SNAPCRAFT_STORE_CREDENTIALS) { + await this.login() + } try { await this.upload() } finally { - await this.logout() + if (!process.env.SNAPCRAFT_STORE_CREDENTIALS) { + await this.logout() + } } } }