Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
5ed50f3
Test against current Hyrax instead of 2.9
laritakr Aug 1, 2026
1eb956b
Drop bolognese in favor of DataCite's JSON API
laritakr Aug 1, 2026
b8bffad
Let a work carry more than one identifier
laritakr Aug 1, 2026
fecfa0e
Move work metadata onto Valkyrie
laritakr Aug 1, 2026
d76a573
Support DOI fields in m3 metadata profiles
laritakr Aug 3, 2026
548ade2
Keep DataCite credentials out of global state
laritakr Aug 4, 2026
76270a9
Build DataCite payloads from work metadata
laritakr Aug 4, 2026
abceb11
Set DOI state explicitly instead of by side effect
laritakr Aug 5, 2026
854af29
Decide DOI eligibility in one place
laritakr Aug 5, 2026
04a94f7
Mint a DOI for a work that was deposited without one
laritakr Aug 5, 2026
dee5e7a
Offer minting from the DOI tab and the work show page
laritakr Aug 5, 2026
98b8870
Keep DataCite in step with a work's later edits
laritakr Aug 5, 2026
d56fbf0
Fill the deposit form from an existing DOI
laritakr Aug 6, 2026
7553810
Show a DOI on the work page, but not a draft one
laritakr Aug 6, 2026
572f341
Retire the last ActiveFedora-era specs
laritakr Aug 6, 2026
5a34195
Make all three generators work on a Valkyrie app
laritakr Aug 9, 2026
e6edec6
Clear out code and config left behind by the rewrite
laritakr Aug 9, 2026
8e47a4f
Document how the gem actually works now
laritakr Aug 9, 2026
a2675c1
Badge the CI that actually runs
laritakr Aug 10, 2026
ef3d67b
Fix what CI and review caught
laritakr Aug 10, 2026
2ccfba4
Start only the web service in CI
laritakr Aug 10, 2026
d247c9e
Let applications tracking Hyrax main install the gem
laritakr Aug 10, 2026
467bd8c
Name the migration what Rails will load
laritakr Aug 10, 2026
56c0693
Save the DOI the deposit form collects
laritakr Aug 10, 2026
4957642
Point the DOI buttons at routes the host serves
laritakr Aug 10, 2026
fe610b6
Show and save the DOI that was reserved
laritakr Aug 10, 2026
06e2ada
Give a reserved DOI its work's metadata
laritakr Aug 10, 2026
f3c840b
Record draft as the intent when a DOI is reserved
laritakr Aug 10, 2026
5939c38
Mint the DOI a depositor asked for
laritakr Aug 10, 2026
f574261
Refuse to register placeholder metadata
laritakr Aug 11, 2026
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: 11 additions & 3 deletions .github/workflows/lint-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,17 @@ jobs:
strategy:
fail-fast: false
matrix:
ci_test_app: [dassie]
# Both flex modes are required -- this gem is platform code. sirenia is the only
# configuration where Valkyrie resources live in Fedora while the gem's
# ActiveRecord tables live in Postgres. freyja runs with Wings loaded, covering
# applications still migrating off ActiveFedora. See CONTRIBUTING.md.
ci_test_app: [koppie, allinson, sirenia, freyja]
ci_node_total: [4]
ci_node_index: [0, 1, 2, 3]
# Compose names its project after the file, so shards of one app would otherwise share
# a set of volumes.
env:
COMPOSE_PROJECT_NAME: hyrax-doi-${{ matrix.ci_test_app }}-${{ matrix.ci_node_index }}
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -68,13 +76,13 @@ jobs:
echo $HYRAX_SHA
- name: Start containers
run: |
GITHUB_SHA=latest docker compose -f docker-compose.yml up -d --quiet-pull --pull missing --no-build
GITHUB_SHA=latest docker compose -f docker-compose-${{ matrix.ci_test_app }}.yml up -d --quiet-pull --pull missing --no-build web
- name: RSpec
env:
CI_NODE_TOTAL: ${{ matrix.ci_node_total }}
CI_NODE_INDEX: ${{ matrix.ci_node_index }}
run: >-
GITHUB_SHA=latest docker compose -f docker-compose.yml exec -T -w /app/samvera/hyrax-doi web sh -c
GITHUB_SHA=latest docker compose -f docker-compose-${{ matrix.ci_test_app }}.yml exec -T -w /app/samvera/hyrax-doi web sh -c
"bundle install && yarn install && rspec_booster --job ${{ matrix.ci_node_index }}/${{ matrix.ci_node_total }}"
- name: Capture Container Logs
if: always()
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@ coverage/
tmp/
rubocop.xml
spec/examples.txt
.DS_Store
node_modules/
yarn.lock
Gemfile.koppie.lock
Gemfile.allinson.lock
Gemfile.dassie.lock
16 changes: 2 additions & 14 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,11 @@ Naming/FileName:

RSpec/ExampleLength:
Max: 10
Exclude:
- "spec/features/**/*"
- "spec/services/bolognese/writers/hyrax_work_writer_spec.rb"

RSpec/AnyInstance:
Exclude:
- "spec/controllers/hyrax_doi_controller_spec.rb"
- "spec/features/autofill_spec.rb"
- "spec/features/create_draft_doi_spec.rb"

RSpec/DescribeClass:
Exclude:
- "spec/features/**/*"
- "spec/controllers/hyrax/doi/mint_actions_spec.rb"
- "spec/services/hyrax/doi/flexible_profile_installer_spec.rb"

RSpec/NestedGroups:
Enabled: false

Rails/Date:
Exclude:
- "spec/services/bolognese/readers/hyrax_work_reader_spec.rb"
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.3.0
378 changes: 378 additions & 0 deletions CHANGELOG.md

Large diffs are not rendered by default.

144 changes: 144 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Contributing to hyrax-doi

Technical guide to developing and testing this gem. For community guidelines — code of
conduct, commit conventions, and the pull request process — see
[docs/CONTRIBUTING.md](docs/CONTRIBUTING.md).

## How the test harness works

This gem has no test application of its own. It runs against Hyrax's test apps, which come
from a git submodule at `vendor/engines/hyrax`. Docker Compose mounts three directories into
the container:

| Host | Container |
|---|---|
| `vendor/engines/hyrax/.koppie` | `/app/samvera/hyrax-webapp` (the Rails app) |
| `vendor/engines/hyrax` | `/app/samvera/hyrax-engine` (Hyrax itself) |
| `.` (this repo) | `/app/samvera/hyrax-doi` (the gem) |

**Specs run from `/app/samvera/hyrax-doi`**, not from the webapp directory.

### The three test apps

As of 1.0.0 this gem is Valkyrie-only, and every configuration must pass. They differ in
metadata backend and schema mode:

| App | Valkyrie metadata | `HYRAX_FLEXIBLE` | Fedora | Wings |
|---|---|---|---|---|
| **koppie** | Postgres | `false` | no | no |
| **allinson** | Postgres | `true` | no | no |
| **sirenia** | Fedora | `false` | yes | no |
| **freyja** | Postgres (via Freyja) | `false` | yes | **yes** |

**Both flex modes are required.** This gem is platform code: `HYRAX_FLEXIBLE=false` uses the
simple YAML schema loader, `true` uses the m3 profile-driven loader, and they resolve
attributes, indexing, and show-page rendering differently. A change that works in one can
silently break the other.

**Sirenia matters** because it is the only configuration where Valkyrie resources live in
Fedora while the gem's ActiveRecord tables live in Postgres.

**Freyja matters** because it is the only configuration with Wings loaded. It runs dassie
with `VALKYRIE_TRANSITION=true`, which swaps in Hyrax's Freyja adapter — reads go through
Wings, writes come back as Valkyrie. That is the shape of an application partway through
migrating off ActiveFedora, and it is a supported configuration: **Wings may be loaded, but
works must be Valkyrie resources.** A work still persisted as an ActiveFedora object cannot
carry a Valkyrie attribute. Note dassie runs Rails 6.1 where the others run 7.2, so it also
catches gem-version assumptions the other three miss.

Allinson mounts the **same `.koppie` app directory** as koppie — it is koppie with flex
enabled, not a separate app. It has its own `Gemfile.allinson` purely so it gets its own
lockfile. Sirenia reuses `Gemfile.koppie` (it differs only in runtime configuration), which
is why there is no `Gemfile.sirenia`.

## Setup

Initialize the Hyrax submodule after cloning:

```
git submodule init
git submodule update
```

> **Port conflicts.** These stacks bind the same host ports as a Hyrax checkout's own
> koppie/allinson/sirenia stacks. If you have those running, stop them first
> (`docker compose -f docker-compose-koppie.yml stop` in your Hyrax checkout). The gem's
> three stacks use staggered ports and do not conflict with each other.

## Running specs

Pick a stack, bring it up, and run rspec from the gem directory:

```
docker compose -f docker-compose-koppie.yml up -d
docker compose -f docker-compose-koppie.yml exec -w /app/samvera/hyrax-doi web bash
bundle install
bundle exec rspec
```

Non-interactively, from the host:

```
docker compose -f docker-compose-koppie.yml exec -T -w /app/samvera/hyrax-doi web \
sh -c "bundle exec rspec spec/services/hyrax/doi/datacite_client_spec.rb"
```

Swap `koppie` for `allinson` or `sirenia` to run the other configurations. **Run all three
before opening a pull request** — CI does.

Each stack needs its own `bundle install` the first time, since allinson uses a different
Gemfile and therefore a different lockfile.

On an Apple Silicon machine, bundler may report that `aarch64-linux` is missing from the
lockfile's platforms. Add it once per lockfile:

```
bundle lock --add-platform aarch64-linux
```

Tear down when finished:

```
docker compose -f docker-compose-koppie.yml down
```

### The `:active_fedora` tag

Specs tagged `:active_fedora` are excluded automatically when Wings is disabled, which is the
case in all three apps. These are ActiveFedora-era specs still awaiting rewrite for Valkyrie;
each will be rewritten or deleted as its part of the port lands. **Do not add new specs with
this tag** — new work should be Valkyrie-native.

## Linting

```
docker compose -f docker-compose-koppie.yml exec -T -w /app/samvera/hyrax-doi web \
sh -c "bundle exec rubocop"
```

Rubocop must pass before a pull request is merged.

It can also run on the host, which is faster for a quick check. `.ruby-version` pins Ruby 3.3
to match the container and CI; without it a version manager may select an older Ruby that
cannot load the gem's rubocop. The container remains authoritative, since it uses the bundled
rubocop version rather than whatever is installed on the host.

Note the two Ruby versions answer different questions: `.ruby-version` (3.3) is what this
project is developed and tested on, while the gemspec's `required_ruby_version` (>= 3.2) is
the minimum an adopting application needs, matching Hyrax's own floor.

## Rake tasks and generators

Hyrax's rake tasks are available under the `app` namespace (e.g. `rake app:db:migrate`).
Rails generators run normally from the gem root (e.g. `rails g job CheckDOIResolution`).

You shouldn't need to run anything from inside `vendor/engines/hyrax` unless explicitly told
to.

## Hyrax version

The submodule currently tracks Hyrax `main` rather than a release tag. The released
`hyrax-v5.3.0` cannot boot: its `Hyrax::Forms::ResourceForm` includes `CompoundFieldBehavior`,
but the tag does not contain the file defining that constant, so loading the form raises
`NameError`. Hyrax 5.3.0 is otherwise the minimum supported version, because it is the first
release containing the flexible metadata stack. Pin to a release tag once a fixed one ships.
5 changes: 5 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ else
gemspec
end

# Match Hyrax's own constraint. Without pinning, bundler resolves erb 6, whose
# ERB.new signature sprockets 3.7.2 cannot call -- the asset pipeline then raises
# "wrong number of arguments (given 3, expected 1)" on any .erb asset.
gem 'erb', '~> 4.0'

group :development, :test do
gem 'ammeter'
gem 'benchmark-ips'
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.allinson
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
eval_gemfile 'Gemfile'

gem 'hyrax-doi', path: '.'
1 change: 0 additions & 1 deletion Gemfile.dassie
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Use dedicated lock files for dassie/koppie to avoid gem mismatches
eval_gemfile 'Gemfile'

gem 'hyrax-doi', path: '.'
Loading
Loading