diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ffeac0b0..b6b8e475 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,6 +7,10 @@ on: pull_request: delete: +defaults: + run: + shell: bash + jobs: build: runs-on: ubuntu-latest @@ -48,6 +52,10 @@ jobs: 'test_project_scratch', 'hello-world', ], + os: [ + 'ubuntu-latest', + 'windows-latest', + ], include: [ { inspect_image: 'test_project_scratch', @@ -57,6 +65,14 @@ jobs: inspect_image: 'hello-world', prepare_command: ':', build_command: 'docker pull hello-world', + }, { + branch: process.env.GITHUB_REF.replace('refs/heads/', '') + } + ], + exclude: [ + { + inspect_image: 'test_project_scratch', + os: 'windows-latest', }, ], } @@ -69,18 +85,13 @@ jobs: needs: build strategy: matrix: ${{ fromJSON(needs.build.outputs.matrix) }} - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 - run: ${{ matrix.prepare_command }} - - name: Extract - id: extract - run: | - echo "##[set-output name=branch;]${GITHUB_REF#refs/heads/}" - - name: Download action uses: actions/download-artifact@v2 with: @@ -88,9 +99,9 @@ jobs: path: action-dlc - uses: ./action-dlc - name: Run satackey/action-docker-layer-caching@${{ steps.extract.outputs.branch }} + name: Run satackey/action-docker-layer-caching@${{ matrix.branch }} with: - key: docker-layer-caching-${{ matrix.inspect_image }}-sha:${{ github.sha }}-{hash} + key: docker-layer-caching-${{ matrix.os }}-${{ matrix.inspect_image }}-sha:${{ github.sha }}-{hash} - run: ${{ matrix.build_command }} @@ -98,7 +109,8 @@ jobs: needs: [build, test_saving] strategy: matrix: ${{ fromJSON(needs.build.outputs.matrix) }} - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + steps: - uses: actions/checkout@v2 @@ -116,10 +128,10 @@ jobs: path: action-dlc - uses: ./action-dlc - name: Run satackey/action-docker-layer-caching@${{ steps.extract.outputs.branch }} + name: Run satackey/action-docker-layer-caching@${{ matrix.branch }} with: - key: never-restored-docker-layer-caching-${{ matrix.inspect_image }}-sha:${{ github.sha }}-{hash} - restore-keys: docker-layer-caching-${{ matrix.inspect_image }}-sha:${{ github.sha }}- + key: never-restored-docker-layer-caching-${{ matrix.os }}-${{ matrix.inspect_image }}-sha:${{ github.sha }}-{hash} + restore-keys: docker-layer-caching-${{ matrix.os }}-${{ matrix.inspect_image }}-sha:${{ github.sha }}- skip-save: 'true' - name: Show cached image info diff --git a/src/ImageDetector.ts b/src/ImageDetector.ts index 1ab23033..f93d9bab 100644 --- a/src/ImageDetector.ts +++ b/src/ImageDetector.ts @@ -5,7 +5,7 @@ export class ImageDetector { async getExistingImages(): Promise { const existingSet = new Set([]) const ids = (await exec.exec(`docker image ls -q`, [], { silent: true })).stdoutStr.split(`\n`).filter(id => id !== ``) - const repotags = (await exec.exec(`sh -c "docker image ls --format '{{ .Repository }}:{{ .Tag }}' --filter 'dangling=false'"`, [], { silent: true })).stdoutStr.split(`\n`).filter(id => id !== ``); + const repotags = (await exec.exec(`docker`, `image ls --format {{.Repository}}:{{.Tag}} --filter dangling=false`.split(' '), { silent: true })).stdoutStr.split(`\n`).filter(id => id !== ``); core.debug(JSON.stringify({ log: "getExistingImages", ids, repotags })); ([...ids, ...repotags]).forEach(image => existingSet.add(image)) core.debug(JSON.stringify({ existingSet })) diff --git a/src/LayerCache.ts b/src/LayerCache.ts index 54c7464f..7f53ad6d 100644 --- a/src/LayerCache.ts +++ b/src/LayerCache.ts @@ -49,8 +49,8 @@ class LayerCache { } private async saveImageAsUnpacked() { - await this.exec('mkdir -p', [this.getSavedImageTarDir()], { silent: true }) - await this.exec(`sh -c`, [`docker save '${(await this.makeRepotagsDockerSaveArgReady(this.ids)).join(`' '`)}' | tar xf - -C ${this.getSavedImageTarDir()}`]) + await fs.mkdir(this.getSavedImageTarDir(), { recursive: true }) + await this.exec(`sh -c`, [`docker save '${(await this.makeRepotagsDockerSaveArgReady(this.ids)).join(`' '`)}' | tar xf - -C .`], { cwd: this.getSavedImageTarDir() }) } private async makeRepotagsDockerSaveArgReady(repotags: string[]): Promise { @@ -133,14 +133,15 @@ class LayerCache { } } - private async storeSingleLayerBy(id: string): Promise { - const path = this.genSingleLayerStorePath(id) - const key = await this.generateSingleLayerSaveKey(id) + private async storeSingleLayerBy(layerId: string): Promise { + const path = this.genSingleLayerStorePath(layerId) + const key = await this.generateSingleLayerSaveKey(layerId) - core.info(`Start storing layer cache: ${key}`) + core.info(`Start storing layer cache: ${JSON.stringify({ layerId, key })}`) const cacheId = await LayerCache.dismissError(cache.saveCache([path], key), LayerCache.ERROR_CACHE_ALREAD_EXISTS_STR, -1) - core.info(`Stored layer cache, key: ${key}, id: ${cacheId}`) + core.info(`Stored layer cache: ${JSON.stringify({ key, cacheId })}`) + core.debug(JSON.stringify({ log: `storeSingleLayerBy`, layerId, path, key, cacheId})) return cacheId } @@ -177,8 +178,9 @@ class LayerCache { } private async restoreLayers(): Promise { - const pool = new PromisePool(this.concurrency) + + const pool = new PromisePool(this.concurrency) const tasks = (await this.getLayerIds()).map( layerId => pool.open(() => this.restoreSingleLayerBy(layerId)) ) @@ -201,9 +203,14 @@ class LayerCache { } private async restoreSingleLayerBy(id: string): Promise { - core.debug(JSON.stringify({ log: `restoreSingleLayerBy`, id })) + const path = this.genSingleLayerStorePath(id) + const key = await this.recoverSingleLayerKey(id) + const dir = path.replace(/[^/\\]+$/, ``) + + core.debug(JSON.stringify({ log: `restoreSingleLayerBy`, id, path, dir, key })) - const result = await cache.restoreCache([this.genSingleLayerStorePath(id)], await this.recoverSingleLayerKey(id)) + await fs.mkdir(dir, { recursive: true }) + const result = await cache.restoreCache([path], key) if (result == null) { throw new Error(`${LayerCache.ERROR_LAYER_CACHE_NOT_FOUND_STR}: ${JSON.stringify({ id })}`) @@ -243,7 +250,7 @@ class LayerCache { } genSingleLayerStorePath(id: string) { - return `${this.getLayerCachesDir()}/${id}/layer.tar` + return path.resolve(`${this.getLayerCachesDir()}/${id}/layer.tar`) } async generateRootHashFromManifest(): Promise { diff --git a/src/Tar.ts b/src/Tar.ts index 99653304..c40ebc2a 100644 --- a/src/Tar.ts +++ b/src/Tar.ts @@ -16,6 +16,7 @@ export function assertManifests(x: unknown): asserts x is Manifests { export async function loadRawManifests(path: string) { return (await fs.readFile(`${path}/manifest.json`)).toString() } + export async function loadManifests(path: string) { const raw = await loadRawManifests(path) const manifests = JSON.parse(raw.toString())