Skip to content

Commit

Permalink
feat: support mount path
Browse files Browse the repository at this point in the history
  • Loading branch information
samypr100 committed May 31, 2024
1 parent a804b2b commit c1fdf33
Show file tree
Hide file tree
Showing 11 changed files with 399 additions and 85 deletions.
126 changes: 115 additions & 11 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ jobs:
drive-format: NTFS
drive-type: Fixed
drive-path: "my_awesome_drive.vhdx"
mount-path: ""
mount-if-exists: false
workspace-copy: true

Expand All @@ -69,6 +70,7 @@ jobs:
fail-fast: false
matrix:
drive-format: [ FAT, FAT32, exFAT, NTFS, ReFS ]
with-mount-path: [ true, false ]
runs-on: windows-2022
steps:
- name: Check out source code
Expand All @@ -77,23 +79,32 @@ jobs:
uses: ./
with:
drive-format: ${{ matrix.drive-format }}
# This should fall back to Drive Letter on unsupported drive formats.
mount-path: ${{ matrix.with-mount-path && 'mount' || '' }}

test-large-size:
strategy:
fail-fast: false
matrix:
drive-type: [ Fixed, Dynamic ]
with-mount-path: [ true, false ]
runs-on: windows-2022
steps:
- name: Check out source code
uses: actions/checkout@v4
- name: Setup Dev Drive
id: setup-drive
uses: ./
with:
drive-size: 10GB
drive-type: ${{ matrix.drive-type }}
mount-path: ${{ matrix.with-mount-path && 'mount' || '' }}

test-drive-path-with-spaces:
test-paths-with-spaces:
strategy:
fail-fast: false
matrix:
with-mount-path: [ true, false ]
runs-on: windows-2022
steps:
- name: Check out source code
Expand All @@ -104,17 +115,65 @@ jobs:
drive-size: 50MB
drive-format: NTFS
drive-path: "path/to/my/dev drive with spaces.vhdx"
mount-path: ${{ matrix.with-mount-path && 'my mount/location/with spaces' || '' }}
- name: Write File to Dev Drive
working-directory: ${{ env.DEV_DRIVE }}
run: New-Item test.txt

test-copy-inside-workspace:
test-mount-path:
strategy:
fail-fast: false
matrix:
is-relative: [ true, false ]
drive-format: [ ReFS, NTFS ]
runs-on: windows-2022
steps:
- name: Check out source code
uses: actions/checkout@v4
- name: Setup Dev Drive
uses: ./
with:
drive-format: ${{ matrix.drive-format }}
mount-path: ${{ matrix.is-relative && 'mount' || format('{0}/mount', github.workspace) }}
- name: Write File to Dev Drive
working-directory: ${{ env.DEV_DRIVE }}
run: |
New-Item test.txt
test-workspace-copy:
strategy:
fail-fast: false
matrix:
with-mount-path: [ true, false ]
workspace-copy: [ true ]
runs-on: windows-2022
steps:
- name: Check out source code
uses: actions/checkout@v4
- name: Setup Dev Drive
id: setup-drive
uses: ./
with:
mount-path: ${{ matrix.with-mount-path && format('{0}/../mount', github.workspace) || '' }}
workspace-copy: ${{ matrix.workspace-copy }}
- name: Check workspace was copied
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
run: |
Get-ChildItem -Force
if (-not $env:DEV_DRIVE_WORKSPACE) {
exit 1
}
if (-not (Test-Path -Path action.yml -PathType Leaf)) {
exit 1
}
test-workspace-copy-edge-cases:
strategy:
fail-fast: false
matrix:
runs-on: [ windows-2022 ]
with-mount-path: [ true, false ]
workspace-copy: [ true, false ]
runs-on: ${{ matrix.runs-on }}
runs-on: windows-2022
steps:
- name: Check out source code
uses: actions/checkout@v4
Expand All @@ -124,12 +183,42 @@ jobs:
uses: ./
with:
drive-path: "${{ github.workspace }}/dev_drive.vhdx"
mount-path: ${{ matrix.with-mount-path && format('{0}/mount', github.workspace) || '' }}
workspace-copy: ${{ matrix.workspace-copy }}
- name: Fail when `workspace-copy` and failure is not the outcome
if: ${{ matrix.workspace-copy && steps.setup-drive.outcome != 'failure' }}
# Dev Drive Location
- name: Check dev drive is inside GitHub workspace
run: |
Get-ChildItem -Force
if (-not (Test-Path -Path dev_drive.vhdx -PathType Leaf)) {
exit 1
}
- name: Check workspace was copied, filtering the dev drive
if: ${{ !matrix.with-mount-path && matrix.workspace-copy }}
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
run: |
Get-ChildItem -Force
if (-not $env:DEV_DRIVE_WORKSPACE) {
exit 1
}
if (Test-Path -Path dev_drive.vhdx -PathType Leaf) {
exit 1
}
if (-not (Test-Path -Path action.yml -PathType Leaf)) {
exit 1
}
# Drive Letter (with Dev Drive inside workspace)
- name: Fail when `workspace-copy` and success is not the outcome when drive letter is being used
if: ${{ !matrix.with-mount-path && matrix.workspace-copy && steps.setup-drive.outcome != 'success' }}
run: exit 1
- name: Fail when not `workspace-copy` and success is not the outcome when drive letter is being used
if: ${{ !matrix.with-mount-path && !matrix.workspace-copy && steps.setup-drive.outcome != 'success' }}
run: exit 1
- name: Fail when not `workspace-copy` and success is not the outcome
if: ${{ !matrix.workspace-copy && steps.setup-drive.outcome != 'success' }}
# Mount Path (with mount inside workspace)
- name: Fail when `workspace-copy` and failure is not the outcome when mount path is inside workspace
if: ${{ matrix.with-mount-path && matrix.workspace-copy && steps.setup-drive.outcome != 'failure' }}
run: exit 1
- name: Fail when not `workspace-copy` and success is not the outcome when mount path inside workspace
if: ${{ matrix.with-mount-path && !matrix.workspace-copy && steps.setup-drive.outcome != 'success' }}
run: exit 1

test-unsupported-os:
Expand All @@ -154,6 +243,10 @@ jobs:
run: exit 1

test-cache-storage:
strategy:
fail-fast: false
matrix:
with-mount-path: [ true, false ]
runs-on: windows-2022
steps:
- name: Check out source code
Expand All @@ -164,21 +257,27 @@ jobs:
drive-size: 50MB
drive-format: NTFS
drive-path: "my_cached_drive.vhdx"
mount-path: ${{ matrix.with-mount-path && format('{0}/mount', github.workspace) || '' }}
mount-if-exists: true
- name: Write File to Dev Drive
working-directory: ${{ env.DEV_DRIVE }}
# Dismount so we can always force-cache the disk via actions/cache/save
run: |
New-Item test.txt
Dismount-VHD -Path ${{ env.DEV_DRIVE_PATH }}
- name: Cache Dev Drive
uses: actions/cache/save@v4
with:
path: ${{ env.DEV_DRIVE_PATH }}
key: test-cache-${{ github.run_id }}
key: ${{ matrix.with-mount-path && format('test-cache-mount-path-{0}', github.run_id) || format('test-cache-drive-letter-{0}', github.run_id) }}
outputs:
dev-drive-path: ${{ env.DEV_DRIVE_PATH }}

test-cache-retrieval:
strategy:
fail-fast: false
matrix:
with-mount-path: [ true, false ]
runs-on: windows-2022
needs: [test-cache-storage]
steps:
Expand All @@ -188,13 +287,18 @@ jobs:
uses: actions/cache/restore@v4
with:
path: ${{ needs.test-cache-storage.outputs.dev-drive-path }}
key: test-cache-${{ github.run_id }}
key: ${{ matrix.with-mount-path && format('test-cache-mount-path-{0}', github.run_id) || format('test-cache-drive-letter-{0}', github.run_id) }}
fail-on-cache-miss: true
- name: Setup Dev Drive
uses: ./
with:
drive-path: "my_cached_drive.vhdx"
mount-path: ${{ matrix.with-mount-path && format('{0}/mount', github.workspace) || '' }}
mount-if-exists: true
- name: Check File in Dev Drive
working-directory: ${{ env.DEV_DRIVE }}
run: Test-Path test.txt -PathType Leaf
run: |
Get-ChildItem -Force
if (-not (Test-Path -Path test.txt -PathType Leaf)) {
exit 1
}
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# 3.0.0

* Allow mounting dev drive in specified mount path (ReFS, NTFS only).
* Workspace copying is no longer restricted by the Dev Dri.ve location.
* Paths in output env vars are no longer escaped `\\`.
* Cleaner error messages.

# 2.2.0

* Improved error handling feedback.
Expand Down
41 changes: 33 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ this action creates for you.
Just add the following line to the `steps:` list in your GitHub Actions yaml:

```yaml
- uses: samypr100/setup-dev-drive@v2
- uses: samypr100/setup-dev-drive@v3
```
You can optionally pass parameters to the action as follows:
```yaml
- uses: samypr100/setup-dev-drive@v2
- uses: samypr100/setup-dev-drive@v3
with:
drive-size: 1GB
drive-format: ReFS
Expand Down Expand Up @@ -74,7 +74,8 @@ workspace drive letter on the runner. Hence, `dev_drive.vhdx` will likely resolv
`C:\dev_drive.vhdx` or `D:\dev_drive.vhdx`.

When an absolute path is provided, make sure it's located outside `${{ github.workspace }}`
otherwise `workspace-copy` can cause issues. This action will raise an error in such cases.
otherwise `workspace-copy` will issue a warning. This action will ignore copying the dev drive
in such scenarios.

#### `drive-type`

Expand All @@ -86,6 +87,15 @@ payload to cache when the job ends.

`Fixed` gives you a notable performance boost, but there's a small creation overhead.

#### `mount-path`

Mounts the dev drive at the specified `mount-path` location. This option is primarily
useful when you want to mount your dev drive inside the GitHub workspace via
`${{ github.workspace }}/my_mount_path` or equivalent.

Note, This is only supported by `NTFS` or `ReFS` drive formats, when using other formats
it will fall back to a drive letter instead.

#### `mount-if-exists`

Mounts the dev drive if it already exists at `drive-path` location. When it does not exist,
Expand All @@ -102,22 +112,35 @@ your workload to be purely on the dev drive.
This option was needed since `actions/checkout` does not allow cloning outside `${{ github.workspace }}`.
See [actions/checkout#197](https://github.com/actions/checkout/issues/197).

This option is compatible with `mount-path` as long as the mount path is not directly located inside your
GitHub workspace (e.g. `${{ github.workspace }}/../my_mount_path`).

## Environment Variables

These environment variables are meant to be used along `working-directory` to make sure
your workflow commands are executing relative to your dev drive.

#### `DEV_DRIVE`

Contains the path to your dev drive of the form `<DRIVE_LETTER>:`. For example if the dev drive
assigned letter is `E`, `${{ env.DEV_DRIVE }}` will contain `E:`.
Contains the path to your dev drive of the form `<DRIVE_LETTER>:` or the canonical `mount-path`.
For example, if the dev drive assigned letter is `E`, `${{ env.DEV_DRIVE }}` will contain `E:`.
Consequently, if your dev drive canonical mount path is `D:\a\path\to\mount`, that will be the
value of the env var.

This env var is always set.

#### `DEV_DRIVE_WORKSPACE`

When `workspace-copy` is set to true, this contains the workspace location as represented
by the dev drive location. For example if your GitHub workspace is `D:\a\<project-name>\<project-name>`
your dev drive workspace will be `E:\<project-name>` by default assuming the drive letter is `E`.

When `mount-path` is set, this behaves the same as described above with the caveat that the `mount-path`
location must be outside your GitHub workspace (e.g. `${{ github.workspace }}/../my_mount_path`).

This env var is only set **if-only-if** `workspace-copy` option is set. Otherwise, it's expected that
you'd use `DEV_DRIVE` env var instead.

#### `DEV_DRIVE_PATH`

The canonical location of the VHDX file.
Expand All @@ -129,13 +152,15 @@ When `drive-path` is set to an absolute path like `D:\path\to\my_drive.vhdx`
the location in this variable will be the same but normalized as given by
[path.normalize](https://nodejs.org/api/path.html#pathnormalizepath).

This env var is always set.

## Examples

#### Setting working directory to use Dev Drive workspace

```yaml
- uses: actions/checkout@v4
- uses: samypr100/setup-dev-drive@v2
- uses: samypr100/setup-dev-drive@v3
with:
workspace-copy: true
- name: Install dependencies in dev drive
Expand All @@ -146,7 +171,7 @@ the location in this variable will be the same but normalized as given by
#### Installing software inside Dev Drive root

```yaml
- uses: samypr100/setup-dev-drive@v2
- uses: samypr100/setup-dev-drive@v3
- name: Install rust toolchain in dev drive
env:
CARGO_HOME: ${{ env.DEV_DRIVE }}/.cargo
Expand All @@ -164,7 +189,7 @@ Inspired by [actions/cache#752 (comment)](https://github.com/actions/cache/issue
with:
path: "C:\\bazel_cache.vhdx"
key: bazel-cache-windows
- uses: samypr100/setup-dev-drive@v2
- uses: samypr100/setup-dev-drive@v3
with:
drive-path: "C:\\bazel_cache.vhdx"
drive-format: NTFS
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ inputs:
drive-type:
description: "Determines whether all space is allocated initially or over time. Example: Fixed or Dynamic."
default: "Dynamic"
mount-path:
description: "Specific mount location for the Dev Drive. Only compatible with NTFS or ReFS."
required: false
mount-if-exists:
description: "Supports mounting an existing VHDX located in `drive-path`, avoiding creation overhead."
default: "false"
Expand Down
4 changes: 2 additions & 2 deletions dist/cleanup/index.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions dist/setup/index.js

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions src/cleanup-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ export async function cleanup(): Promise<void> {
return
}

core.info('Attempting to remove Dev Drive...')
core.info('Attempting to remove Dev Drive.')

const mountedPath = core.getState(StateVariables.DevDrive)
core.debug(`Retrieved State ${StateVariables.DevDrive}=${mountedPath}`)

const drivePath = core.getState(StateVariables.DevDrivePath)
core.debug(`Retrieved State ${StateVariables.DevDrivePath}=${drivePath}`)

const ret = await dismount(drivePath)
core.info(`Removal completed with exit code ${ret}...`)
const ret = await dismount(drivePath, mountedPath)
core.info(`Removal finished with exit code ${ret}.`)
}
Loading

0 comments on commit c1fdf33

Please sign in to comment.