Skip to content

Releases: shiroemons/gcs-mimic

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 10:49

gcs-mimic 0.7.0

0.7.0 makes gcs-mimic a drop-in replacement for an existing fake-gcs-server
deployment: the image name is the only required change, and fake-gcs-server
flags and FAKE_GCS_* variables now start the server with a warning instead
of stopping it. It also adds a verified Rails Active Storage setup for
development and test, and SDK setup for Go, Ruby, Node.js, Python and PHP.
It publishes ghcr.io/shiroemons/gcs-mimic:0.7.0 for linux/amd64 and
linux/arm64, mirrors the same digest to Docker Hub as
shiroemons/gcs-mimic:0.7.0, and publishes native archives for all eight
macOS, Windows and Linux targets. The 0.6.0 release notes describe
the previous published release; the feature matrix
lists the exact supported subsets.

Changes

fake-gcs-server settings

  • serve translates fake-gcs-server flags (one or two hyphens) and the known
    FAKE_GCS_* variables that have a native equivalent: scheme, host and port,
    HTTP port, external URL, public host, data, TLS files, CORS headers,
    location and log level. Each one logs a warning naming its GCS_MIMIC_*
    replacement. A flag outranks a variable, as in fake-gcs-server, and within
    one source a translation overrides a native value with a warning, so the
    image's own GCS_MIMIC_LISTEN does not defeat an existing FAKE_GCS_PORT.
  • A command line that starts with a fake-gcs-server flag runs serve, so a
    Compose command written for fake-gcs-server works unchanged.
  • -backend memory and -filesystem-root only warn. Data is kept in
    GCS_MIMIC_DATA_DIR; -filesystem-root is not used as the data directory,
    because a reused fake-gcs-server volume is owned by root and the image runs
    as UID 10001.
  • Event settings (-event.*, FAKE_GCS_EVENT_*) and unknown backends still
    stop startup, so a test that waits for notifications fails visibly.
  • Helper commands such as healthcheck and url still reject legacy names.

See legacy setting aliases.

Container healthcheck

  • When gcs-mimic runs as PID 1, as in the image, and the probe derived from
    the environment fails, gcs-mimic healthcheck retries with the server's own
    command-line options, so a Compose command such as -scheme http no
    longer leaves the container unhealthy. Ordinary setups never read them.
    On Apple Silicon, a read-only amd64 container under Rosetta cannot use this
    fallback, because Rosetta needs a writable root to emulate the process's
    /proc entry; use the native arm64 image or GCS_MIMIC_* variables there.

Authentication

  • In strict mode, an unknown bearer token shaped like a JWT, such as the
    self-signed token googleauth sends for a non-Google universe_domain, logs
    one auth_self_signed_jwt_rejected warning per process. The 401 Invalid Credentials response is unchanged, and the token is not logged.

Documentation

  • Rails Active Storage: one config/storage.yml
    entry with a non-Google universe_domain lets Active Storage use the
    emulator in development and test without contacting Google OAuth, while
    production keeps its own entry. The page covers the bucket file with CORS,
    Rails in Compose with the gcs.localhost alias, and CI.
  • SDK setup gives copyable Go, Ruby, Node.js, Python and PHP
    settings and notes where STORAGE_EMULATOR_HOST differs between SDKs.
  • The README was rewritten around the quick start, Compose, SDK setup and
    migration. The quick start now retries the first request with
    --retry-all-errors, because the published port can return an empty reply
    right after docker run.

SDK tests

  • just check-active-storage adds attachments.rb, which checks the
    documented storage.yml entry through a has_one_attached model: uploads,
    URLs, redirect and proxy serving, V2 and V4 direct uploads with
    browser-equivalent CORS requests, no OAuth request 400 days after startup,
    and a production boot that generates no key.

Compatibility and migration

0.7.0 uses the same catalog schema, 35, as 0.6.0, so a data directory from
0.6.0 needs no migration. Upgrading from 0.4.1 or earlier also applies the
0.5.0 migration.

  • fake-gcs-server flags and FAKE_GCS_* variables that stopped startup in
    0.6.0 now start the server and warn. Remove them, or rename them to the
    GCS_MIMIC_* names in the warnings, to silence the warnings.
  • Within one source, a FAKE_GCS_* value now overrides a GCS_MIMIC_* value
    for the same setting. Remove one of them if both are set.
  • Rails apps that followed the earlier application-built Active Storage recipe
    should switch to the storage.yml entry: the earlier recipe's one-day token
    expiry made googleauth try to refresh at Google after a day.

Verification

The release workflow
creates this Release only after validate, including the dependency freshness
check, Foundation and all eight native build/test jobs succeed at the tag's
SHA. The
container workflow
then builds both Linux architectures natively, verifies their SBOM and
provenance, publishes the multi-architecture tag and checks anonymous pulls,
and the Docker Hub workflow mirrors that digest.

Before the release commit, the pre-push checks passed locally on macOS: format,
clippy, cross-compilation checks including the Linux glibc target, all 49 Rust
test binaries and doctests, the compatibility ledger check, the pinned Go,
Ruby, Node.js, Python and PHP SDK suites, and both Linux container smoke
tests. The release-input freshness check
(cargo xtask dependencies check --scope release) reported every input
current.

The first pre-push run failed the linux/amd64 container smoke test: on Apple
Silicon, Rosetta crashed the healthcheck while it read /proc/1/cmdline on the
read-only root, and the published 0.6.0 image stayed healthy in the same
setup. The healthcheck now reads PID 1's options only after the environment's
probe fails, and the complete pre-push run passed on the final source.

just check-active-storage, which is not part of the pre-push checks, passed
its storage.yml cases (10 PASS) and production check; its scenario still
reports the known default-authentication failure of an entry without
universe_domain, as in earlier releases. A Rails app with Puma was checked
in Chrome with Rails on the host and in Compose; see the
Active Storage scenario.

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 07:53

gcs-mimic 0.6.0

0.6.0 is a reliability release. One faulty request, background job or panic no
longer stops the server or leaves it silently degraded, failed writes and
syncs no longer publish short objects, and readiness reports stopped
background work. It regenerates the built-in development TLS CA so Python
3.13+ clients pass their default strict checks, accepts the Node.js SDK's
default single-request resumable upload, and adds official Node.js, Python and
PHP SDK suites. It publishes ghcr.io/shiroemons/gcs-mimic:0.6.0 for
linux/amd64 and linux/arm64, mirrors the same digest to Docker Hub as
shiroemons/gcs-mimic:0.6.0, and publishes native archives for all eight
macOS, Windows and Linux targets. The 0.5.0 release notes describe
the previous published release; the feature matrix
lists the exact supported subsets.

The built-in development CA changed. HTTPS clients that trust a CA exported
from 0.5.0 or earlier must export it again; see
Compatibility and migration.

Changes

Uploads

  • Resumable uploads accept the open-ended Content-Range: bytes start-*/total
    and bytes 0-*/* forms as a final request, as the Node.js SDK sends for its
    default single-request upload. A known total, a declared Content-Length or
    the end of a chunked body fixes the object size; the body stays bounded by
    the object size limit. Short, long, gapped and conflicting requests fail
    without advancing the acknowledged prefix.

Local HTTPS

  • The built-in development CA, leaf certificate and leaf key now carry Subject
    and Authority Key Identifiers, so Python 3.13+ clients accept the server
    with their default VERIFY_X509_STRICT checks. Subject names, P-256 keys,
    SANs and the ten-year validity are unchanged.
    scripts/tls-development-cert.sh regenerates the set reproducibly and checks
    the chain with -x509_strict. See Local HTTPS.

Durability

  • Uploads, resumable chunks and copy, rewrite and compose transfers flush each
    blob before syncing it. A failed final write previously went unreported, so
    an upload could publish metadata for the full size over a shorter blob.
  • Appendable objects write and sync through one file descriptor, so a sync
    reports an earlier writeback failure. A failed sync rolls the writer back to
    its persisted size, so the client must send those bytes again.
  • A cancelled append keeps its writer slot until its file operation ends, so
    it cannot write through an old descriptor after a takeover.
  • Finalizing an appendable object removes its appendable record in the same
    transaction that publishes the generation. A failed separate cleanup could
    previously make a deleted object serve its old bytes again.

Fault isolation and readiness

  • A panicking HTTP connection is logged and closed; the server keeps
    accepting other connections. Previously it stopped the whole server.
  • A panic inside a catalog operation rolls back its transaction and fails only
    that request. Previously every later request returned 503 until restart.
  • Publication workers and the blob shard creator keep working after a
    panicking job.
  • Background tasks run supervised. Resumable maintenance restarts after a
    panic with exponential backoff; readiness turns off after three consecutive
    failed passes and recovers on the next successful one.
  • /_internal/ready turns off when the sync mirror stops, instead of staying
    200. Transient mirror failures, such as catalog contention or interrupted
    I/O, are retried with backoff; invalid names, permission errors, corruption
    and panics still stop the mirror.
  • Seeding fails when the directory walk stops before it finishes, instead of
    marking a partial seed complete.

Error reporting

  • Compose, copy, rewrite and resumable chunk transfers report a corrupt
    catalog or a full disk with the same actionable 503 message as single-shot
    uploads, instead of a generic backendError. Status codes are unchanged.
  • A closed catalog is reported as closed instead of full.
  • On Windows, a blob destination without a file name returns an error instead
    of panicking.

Downloads

  • Object downloads no longer lose their last chunk when the body producer
    finishes. Rarely, and more often under load, a response previously ended
    before its Content-Length.

Performance

  • The default --max-blocking-threads (GCS_MIMIC_MAX_BLOCKING_THREADS) is
    8 instead of 2, so one slow fsync no longer stalls every other transfer. The
    accepted range is still 1–32.
  • The catalog runs its operations on a dedicated thread instead of the shared
    blocking pool, so file I/O and gzip work no longer delay metadata requests.
  • Request paths and request-driven maintenance reuse cached prepared
    statements.
  • HTTP and gRPC object bodies stream without zero-filling or copying each
    frame. Chunk sizes, channel capacities and limits are unchanged.

SDK tests

  • just check-sdk also runs pinned official Node.js, Python and PHP SDK
    suites against isolated permissive and strict servers over HTTP and HTTPS,
    beside the Go and Ruby suites. See sdk-tests.

Build and checks

  • just check also runs Clippy for the Linux glibc target, so size lints that
    depend on Linux std types fail locally rather than only in CI.
  • The release workflow's freshness gate checks only inputs that build or ship
    release artifacts: the Rust toolchain, direct Cargo dependencies, GitHub
    Actions and the container build and runtime images. SDK suite dependencies
    and test-only images are still checked daily but no longer block a release.
    See the dependency policy.
  • Production code passes a lint gate, cargo xtask lint, that rejects
    unsupervised spawns, uncached SQL on request paths, stringified errors and
    file syncs without a preceding flush. See Development.

Compatibility and migration

0.6.0 uses the same catalog schema, 35, as 0.5.0, so a data directory from
0.5.0 needs no migration. Upgrading from 0.4.1 or earlier also applies the
0.5.0 migration.

  • The built-in development CA is new. A CA exported from gcs-mimic 0.5.0 or
    earlier does not verify the 0.6.0 certificate. Run gcs-mimic tls ca again
    and replace the copy that your clients, containers or test profiles trust.
    Deployments that set GCS_MIMIC_TLS_DIR to a custom CA are unaffected.
  • /_internal/ready, and therefore the container healthcheck, now reports not
    ready when the sync mirror stops or resumable maintenance keeps failing.
    0.5.0 reported ready in both cases.
  • The default blocking thread cap rose from 2 to 8. Set
    --max-blocking-threads 2 to keep the earlier bound.
  • Resumable requests with Content-Range: bytes 0-*/* returned 400 in 0.5.0
    and now finalize the upload.

Verification

The release workflow
creates this Release only after validate, including the dependency freshness
check, Foundation and all eight native build/test jobs succeed at the tag's
SHA. The
container workflow
then builds both Linux architectures natively, verifies their SBOM and
provenance, publishes the multi-architecture tag and checks anonymous pulls,
and the Docker Hub workflow mirrors that digest.

Before the release commit, the pre-push checks passed locally on macOS: format,
clippy, cross-compilation checks including the Linux glibc target, all 49 Rust
test binaries and doctests, the compatibility ledger check, the pinned Go,
Ruby, Node.js, Python and PHP SDK suites, and both Linux container smoke
tests. The Foundation checks passed in CI at 526e066, the last code change
before this release. The release-input freshness check
(cargo xtask dependencies check --scope release) reported every input
current.

The full freshness check reports one development-only drift, recorded as the
composer-riscv64-publication-lag exception: the official composer:latest
index still carries the 2.10.3 riscv64 image, so it differs from the pinned
Composer 2.11.0 index used by the PHP SDK suite and scorecard. The amd64 and
arm64 images are identical under both indexes, and no release artifact
contains Composer.

Known limitations

  • The Node.js, Python and PHP suites cover the basic API milestone and local
    transport, not full SDK compatibility; each suite's README records the
    journeys it does not cover.
  • The 0.5.0 known limitations still apply.

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 29 Oct 13:38

gcs-mimic 0.5.0

0.5.0 extends the SDK scorecard from Go and
Ruby to five official SDKs: gcs-mimic passes 57 of 57 Go probes and 51 of 51
probes each for Ruby, Node.js, PHP and Python. It adds ACL replacement through
bucket and object PATCH and PUT, bounded response replay for media, multipart
and copy invocation tokens, bounded gzip expansion on JSON media downloads and
JSON object metadata HEAD. It publishes ghcr.io/shiroemons/gcs-mimic:0.5.0
for linux/amd64 and linux/arm64, mirrors the same digest to Docker Hub as
shiroemons/gcs-mimic:0.5.0, and publishes native archives for all eight
macOS, Windows and Linux targets. The 0.4.1 release notes describe
the previous published release; the feature matrix
lists the exact supported subsets.

The first start migrates the data directory to a catalog schema that 0.4.1
cannot open. Read Compatibility and migration
before upgrading a persistent deployment.

Changes

Access control

  • Bucket PATCH and PUT accept acl and defaultObjectAcl, and object PATCH
    and PUT accept acl. A supplied array replaces the stored entries, an empty
    array clears them and omission keeps them. Replacement needs both the
    metadata update permission and the resource's setIamPolicy permission.
    The ACL and the other supplied metadata commit in one transaction with one
    metageneration increment; invalid entries, missing permissions, failed
    preconditions, uniform bucket-level access and public access prevention roll
    back the whole update. See the ACL contract.

Objects

  • Media and multipart uploads and JSON copy accept an
    X-Goog-Gcs-Idempotency-Token with or without generation conditions. A
    matching retry returns the original response, even after a later overwrite,
    deletion or restart, and concurrent identical requests publish one
    generation. A conflicting request with the same token returns 400. Completed
    invocations are kept for ten minutes, at most 4096 entries of up to 64 KiB
    each; a full store rejects new tokens with 503. Current permissions are
    checked on every retry. See the
    upload replay contract.
  • JSON media downloads of objects stored with Content-Encoding: gzip are
    decompressed in bounded buffers unless the client accepts gzip or the object
    has Cache-Control: no-transform. Decompressed responses ignore Range,
    keep the stored hashes and ETag, and abort on corrupt or oversized data.
  • JSON object metadata HEAD selects the same generation and applies the same
    conditions and permissions as GET, without a response body.
  • Object move accepts an empty JSON object as its body, as the Node.js SDK
    sends, and still rejects meaningful body fields. Compose accepts a null
    source generation, and object retention accepts a null nested
    retentionExpirationTime, as the Python SDK sends.

Uploads

  • Resumable chunks may repeat whole-object MD5 and CRC32C declarations, as the
    PHP SDK sends. The declarations persist with the acknowledged offset and are
    verified against the complete object at finalization; conflicting or new
    declarations, including on retries of a completed upload, return 400 without
    changing the object.
  • After initiation, a repeated X-Upload-Content-Type, as the Python SDK
    sends, is validated and treated as advisory. Empty, malformed or duplicate
    values return 400.

JSON API

  • Boolean query parameters also accept Python's True and False spellings.
    Other spellings, such as TRUE, 0 or 1, still return 400.

SDK scorecard

  • Node.js, PHP and Python probes run alongside Go and Ruby over a shared,
    verified HTTPS transport. The runner records clean-source state and derived
    SDK metadata with each result, keeps early errors, and the PHP probe signs
    URLs for the final endpoint.

Tests

  • Test fixtures close catalog handles before removing their directories, and
    Unix runs now fail tests that leave files open, so Windows cleanup failures
    are caught on every platform.

Compatibility and migration

The first start migrates the catalog from PRAGMA user_version = 34 (0.4.0 and
0.4.1) to 35, adding the invocation replay table. The migration is one-way:
after it runs, 0.4.1 and earlier releases refuse to open the data directory.
Back up the data directory before upgrading if you may need to roll back.
Upgrading from 0.3.0 or earlier also applies the
0.4.0 migration.

  • Media and multipart uploads with an invocation token but no
    ifGenerationMatch returned 501 in 0.4.1 and now succeed. A retry of a
    committed conditioned upload with the same token now returns the original
    object instead of 412. Tests that relied on either response need updating.
  • PATCH and PUT bodies that change acl or defaultObjectAcl returned 400 in
    0.4.1 and now replace the ACL. Strict-mode callers without setIamPolicy
    now receive 403 for those fields; a caller with getIamPolicy can still echo
    the unchanged ACL.
  • JSON media downloads of gzip-encoded objects without Accept-Encoding: gzip
    now return decompressed bytes. Send Accept-Encoding: gzip or set
    Cache-Control: no-transform to keep the stored bytes.
  • Object metadata HEAD returned 405 in 0.4.1.

Verification

The release workflow
creates this Release only after validate, including the dependency freshness
check, Foundation and all eight native build/test jobs succeed at the tag's
SHA. The
container workflow
then builds both Linux architectures natively, verifies their SBOM and
provenance, publishes the multi-architecture tag and checks anonymous pulls,
and the Docker Hub workflow mirrors that digest.

Before the release commit, the pre-push checks passed locally on macOS: format,
clippy, cross-compilation checks, all Rust test binaries, the compatibility
ledger check, the pinned Go and Ruby SDK suites, including the Ruby strict
profile, and both Linux container smoke tests. The dependency freshness check
reported every input current. The
SDK scorecard at
e7fb384 recorded 100 for gcs-mimic, 44.9 for fake-gcs-server 1.56.1 and 41.5
for gcp-storage-emulator v2026.07.19; later changes touch only tests, the
scorecard runner and documentation.

Known limitations

  • Invocation token replay covers media, multipart and JSON copy only; XML,
    resumable initiation, PATCH, DELETE, rewrite and compose retries execute
    again. The ten-minute retention and capacity limits are local choices, not
    Google's cache policy.
  • Gzip expansion applies only to JSON media GET; XML downloads return the
    stored bytes. JSON media HEAD and collection HEAD are unsupported.
  • The Node.js, PHP and Python results cover the scorecard's permissive,
    default-location HTTPS profile. Node.js V4 signing omits a nondefault port
    from the canonical host, so strict-mode signing at such an endpoint fails.
  • The 0.4.0 known limitations still apply.

v0.4.1

Choose a tag to compare

@github-actions github-actions released this 29 Oct 07:35

gcs-mimic 0.4.1

0.4.1 is the first published release with the
0.4.0 changes: JSON ACL resources, project HMAC keys and the
service agent, bucket notification configurations, Autoclass, storage class on
write, object retention, customer-supplied encryption keys, V4 signed POST
policy uploads and gRPC appendable objects. The v0.4.0 tag exists, but its
Windows release builds failed a test cleanup, so nothing was published for it.
0.4.1 adds one security fix on top. It publishes
ghcr.io/shiroemons/gcs-mimic:0.4.1 for linux/amd64 and linux/arm64,
mirrors the same digest to Docker Hub as shiroemons/gcs-mimic:0.4.1, and
publishes native archives for all eight macOS, Windows and Linux targets. The
0.3.0 release notes
describe the previous published release.

Upgrading from 0.3.0 migrates the data directory to a catalog schema that
0.3.0 cannot open. Read the
0.4.0 compatibility and migration notes
before upgrading a persistent deployment.

Changes since 0.4.0

Security

  • PATCH and PUT accept an acl or defaultObjectAcl field that repeats the
    stored ACL only when the caller may read that ACL. In strict mode, a caller
    with update permission but without the matching getIamPolicy permission
    could previously tell whether a guessed ACL matched the stored one, because a
    match was accepted and anything else was rejected. Such callers now get the
    same 400 response whatever the stored ACL is. Permissive mode is unaffected.

Tests

  • Four object retention wire tests now stop their server before the test
    directory is removed. Windows cannot delete files the catalog still holds,
    which made the 0.4.0 Windows release builds fail.

Compatibility and migration

0.4.1 uses the same catalog schema, 34, as the unpublished 0.4.0. From 0.3.0
or earlier, follow the
0.4.0 compatibility and migration notes:
the first start migrates the catalog from schema 27 one-way, so back up the data
directory if you may need to roll back.

Strict-mode clients that echoed an unchanged ACL in PATCH or PUT without
getIamPolicy permission now receive 400; drop the field or grant the
permission.

Verification

The release workflow
creates this Release only after validate, including the dependency freshness
check, Foundation and all eight native build/test jobs succeed at the tag's
SHA. The
container workflow
then builds both Linux architectures natively, verifies their SBOM and
provenance, publishes the multi-architecture tag and checks anonymous pulls,
and the Docker Hub workflow mirrors that digest.

Before the release commit, all Rust test binaries, format, clippy and the
compatibility ledger check passed locally on macOS, and the Foundation checks,
including the Windows portability tests, passed in CI at the commit that
carries both fixes. The 0.4.0 notes record the earlier SDK suite, container
smoke and SDK scorecard
results; the fixes since then change only ACL echo handling and test cleanup.

Known limitations

The 0.4.0 known limitations still apply.

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 29 Oct 00:44

gcs-mimic 0.3.0

0.3.0 makes fixture loading work like fake-gcs-server: mount a
BUCKET/OBJECT tree at /data and it is applied on every startup, with no
other setting. It also implements gRPC CancelResumableWrite, lists legacy v1
buckets across projects when the project is omitted, and keeps directory
synchronization running past names the host cannot represent. It publishes
ghcr.io/shiroemons/gcs-mimic:0.3.0 for linux/amd64 and linux/arm64,
mirrors the same digest to Docker Hub as shiroemons/gcs-mimic:0.3.0, and
publishes native archives for all eight macOS, Windows and Linux targets. The
0.2.1 release notes
describe the previous release; the feature matrix lists
the exact supported subsets.

Seeding behavior changes in ways that can overwrite API changes on restart.
Read Compatibility and migration before
upgrading a deployment that sets a seed directory or mounts /data.

Changes

Seed files

  • A configured seed directory is applied before readiness on every startup,
    not only when a data directory is first initialized. Missing buckets and
    objects are created. An object whose bytes or metadata differ from what
    seeding writes, including API metadata edits, is replaced as a new
    generation; only an exact match keeps its generation. Objects without a seed
    file are kept, and removing a seed file never deletes an object.
  • A held or retained object that needs replacement is left unchanged, counted
    as blocked and reported by a seed_blocked warning.
  • Regular files directly under the seed root, such as README.md, are skipped
    with a seed_skipped warning instead of stopping startup.
  • The new default_seed_dir setting (--default-seed-dir,
    GCS_MIMIC_DEFAULT_SEED_DIR, JSON default_seed_dir) is used only when
    seed_dir is unset and the directory exists without overlapping data_dir
    or sync_dir. The image sets it to /data.
  • seed_content_type now defaults to extension, so logo.png is stored as
    image/png. The same setting governs files ingested from sync_dir.
  • The ready event's seed field reports buckets, objects, replaced,
    unchanged, blocked and skipped_os_metadata.

See the seed replay change and
loading local files for details.

gRPC

  • Storage v2 CancelResumableWrite discards a resumable session through the
    same catalog cancellation as the JSON session DELETE. Later status queries,
    writes and repeated cancellation return NOT_FOUND; a finalized upload
    returns FAILED_PRECONDITION and keeps its object. Strict mode requires
    storage.objects.create, as resumed writes do.
  • In strict mode, anonymous callers of Storage v2 object I/O and update/copy
    RPCs now receive UNAUTHENTICATED, like JSON, XML and the other RPCs. They
    previously received PERMISSION_DENIED.
  • Legacy Storage v1 ListBuckets without a project lists every project's
    buckets in name order, as the reference emulator does, instead of returning
    INVALID_ARGUMENT. Strict callers see only projects where they hold
    storage.buckets.list.

Directory synchronization

  • Object names with : or \ components are recorded as findings and
    skipped on every OS instead of stopping the whole mirror, so later objects
    keep exporting. Matching host files are counted as unrepresentable.

Distribution

  • The release workflow mirrors the verified GHCR index to Docker Hub without
    rebuilding, so both registries serve the same digest.

Compatibility and migration

The data-directory schema remains PRAGMA user_version = 27, shared with
0.2.0 and 0.2.1, so these releases open each other's data directories. No
catalog migration runs.

  • Deployments that set seed_dir and then change seeded objects through the
    API see those changes replaced on the next restart. Remove seed_dir after
    the first start, or move fixtures that should stay editable out of the seed
    tree.
  • Objects seeded as application/octet-stream by earlier releases are
    replaced once with the extension-derived type. Set
    GCS_MIMIC_SEED_CONTENT_TYPE=octet-stream to keep the previous type, which
    also restores it for sync_dir ingestion.
  • An image deployment that mounts something other than fixtures at /data,
    without using it as data_dir or sync_dir, now seeds from it. Mount it
    elsewhere, or set GCS_MIMIC_SEED_DIR to the intended fixture directory.
  • The ready event's seed.existing_objects field and the skipped outcome are
    removed; read unchanged and replaced instead.
  • Strict gRPC clients that matched PERMISSION_DENIED for anonymous Storage v2
    object calls should expect UNAUTHENTICATED.

Verification

The release workflow
creates this Release only after validate, including the dependency freshness
check, Foundation and all eight native build/test jobs succeed at the tag's
SHA. The
container workflow
then builds both Linux architectures natively, verifies their SBOM and
provenance, publishes the multi-architecture tag and checks anonymous pulls,
and the Docker Hub workflow mirrors that digest.

Before the release commit, Foundation checks passed on Linux with the pinned
and current stable Rust, the macOS, Windows and Linux musl portability tests,
both native container smoke tests, including seed replay and the implicit
/data mount, and the pinned Go SDK suite. The pinned Ruby SDK suite passed
locally on macOS.

Known limitations

  • Seeding has no file watcher and no reseed endpoint; restart to apply edits.
  • Seed replay is applied file by file, not as one directory-wide transaction.
  • The 0.1.0 known limitations and the feature matrix still apply
    to unimplemented API areas.

v0.2.1

Choose a tag to compare

@github-actions github-actions released this 28 Oct 12:46

gcs-mimic 0.2.1

0.2.1 makes catalog schema upgrades visible: a data directory written by a
newer release is rejected with recovery instructions, and an upgrade migration
is logged. It publishes ghcr.io/shiroemons/gcs-mimic:0.2.1 for linux/amd64
and linux/arm64 and native archives for all eight macOS, Windows and Linux
targets. The 0.2.0 release notes
describe the gRPC listener, bucket and object policies and HTTP/1.1 behavior;
the feature matrix lists the exact supported subsets.

Changes

  • Starting with a data directory whose catalog schema is newer than the
    release supports now fails with a data_dir diagnostic that names the
    stored and supported schema versions and the ways to recover: run a release
    that supports the schema, restore a backup taken before the upgrade, or use
    a different data directory. It previously reported only
    catalog unavailable or already in use. The catalog file is not modified.
  • Migrating a data directory from an older schema logs one info event,
    catalog_schema_migrated, with from and to versions before ready.
    New and already current data directories log none, and a log_level of
    warn or error hides it.
  • Release build jobs keep Windows test files on the workspace volume and build
    their test binaries with line tables only.

Compatibility and migration

No migration is required. The data-directory schema remains
PRAGMA user_version = 27, shared with 0.2.0, so 0.2.0 and 0.2.1 open each
other's data directories. Only 0.2.1 and later explain a newer schema; 0.2.0
and 0.1.x still report catalog unavailable or already in use. Upgrading from
0.1.x migrates schema 21 to 27 as described in the 0.2.0 notes; back up the
data directory first.

Verification

The release workflow
creates this Release only after validate, including the dependency freshness
check, Foundation and all eight native build/test jobs succeed at the tag's
SHA. The
container workflow
then builds both Linux architectures natively, verifies their SBOM and
provenance, publishes the multi-architecture tag and checks anonymous pulls.

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 28 Oct 09:04

gcs-mimic 0.2.0

0.2.0 adds an opt-in gRPC listener for Storage v2 and the legacy Storage v1
migration profile, bucket and object policies that the Go and Ruby SDKs use,
and HTTP/1.1 connection behavior closer to Cloud Storage: persistent
connections and documented, retryable timeout responses. It publishes
ghcr.io/shiroemons/gcs-mimic:0.2.0 for linux/amd64 and linux/arm64 and
native archives for all eight macOS, Windows and Linux targets. The
0.1.0 release notes
describe the base workflows; the feature matrix lists
the exact supported subsets.

Upgrading migrates the data directory to a schema that 0.1.x cannot open, and
several responses change. Read Compatibility and migration
before upgrading.

Changes

gRPC

  • --grpc-listen (GCS_MIMIC_GRPC_LISTEN, JSON grpc_listen) starts an
    optional plaintext h2c listener for google.storage.v2.Storage. It serves
    bucket CRUD, updates, IAM and retention locking; object metadata, media,
    listing, deletion and restore; resumable writes; rewrite, compose and move;
    and bidirectional ranged reads through the same catalog and authorization
    as JSON. CancelResumableWrite, Rapid append, unsupported fields and other
    RPCs return non-retryable UNIMPLEMENTED with ErrorInfo. Point Go clients
    at it with STORAGE_EMULATOR_HOST_GRPC.
  • The same listener serves the twelve legacy Storage v1 RPCs of the reference
    emulator as a migration profile, without a Google GA fidelity claim.
  • Idle gRPC connections close with GOAWAY, dead peers are detected with
    HTTP/2 keepalive, and an open stream silent for 60 seconds is closed.

Buckets

  • Uniform bucket-level access, including the 90-day lock and rejection of ACL
    parameters while it is enabled.
  • Retention policies with locking, enforced on deletes and overwrites.
  • Soft delete policies, with deleted and replaced generations kept until their
    hard-delete time.
  • Lifecycle rules are validated, stored and returned; they are not executed.
  • Regional and predefined dual-region location names in bucket creation,
    default_location and the bucket initializer. Physical placement is not
    simulated.
  • buckets.testIamPermissions answers with the authorization real operations
    use.

Objects

  • Temporary holds and monotonic customTime.
  • objects.restore of soft-deleted generations and softDeleted listings.
  • Atomic same-bucket objects.move that reuses the stored bytes.
  • matchGlob filtering for JSON object listings.

Authentication

  • Path-style legacy V2 RSA signed URLs for GET and PUT. Strict mode verifies
    them with registered keys; permissive mode ignores credentials as it does
    for V4.

Directory synchronization

  • The synchronized directory is scanned after readiness: external creates,
    edits and rename targets are ingested with inherited metadata, and buckets
    deleted through the API are not recreated from leftover directories.
    External deletions are not yet ingested.

HTTP behavior

  • HTTP/1.1 connections stay open between requests. An idle connection closes
    after the new keep_alive_timeout_ms (--keep-alive-timeout-ms,
    GCS_MIMIC_KEEP_ALIVE_TIMEOUT_MS; default 120000, range 1–600000), or at
    once when every max_connections slot is taken. An error response to a
    request that carried a body sends Connection: close.
  • A deadline that expires before a response now returns
    408 uploadBrokenConnection for object uploads and 503 backendError for
    other requests, instead of closing the connection without a response.
  • After an early rejection the server keeps reading the rest of the request
    body for up to 30 seconds, so clients read the rejection instead of a reset.
  • Recognized but unsupported inputs return 400 badRequest (XML:
    400 InvalidArgument) instead of 501, so SDKs stop retrying them.
  • No-op defaults sent by the Ruby SDK, such as an empty
    X-Upload-Content-Type, are accepted.
  • A media read failure after the response headers is logged as
    object_body_read_failed with its cause.

Distribution and tooling

  • SHA256SUMS uses LF line endings for every entry, so macOS
    shasum --check verifies the Windows archives too.
  • The daily dependency freshness check handles Go modules that publish only
    pseudo-versions. Dependencies were refreshed, including tonic 0.14.8 and
    the rebuilt rust:1.99.1-slim-trixie base image.

Compatibility and migration

  • Back up the data directory before upgrading. On first start, 0.2.0
    migrates it from schema 21 (PRAGMA user_version = 21, used by 0.1.0
    through 0.1.3) to schema 27. 0.1.x releases refuse to open the migrated
    directory and report only catalog unavailable or already in use;
    downgrading requires the backup.
  • Responses for recognized but unsupported inputs change from 501 to 400, and
    known Google JSON routes that are not implemented, such as ACLs,
    notifications and HMAC keys, change from 404 to the same 400. Missing
    resources and unknown paths still return 404.
  • Bucket PUT (buckets.update) now keeps omitted settings instead of
    resetting them; explicit null and empty values keep their field rules.
  • Clients that read a response until the server closes the connection must
    send Connection: close or use the response's Content-Length. SDKs and
    standard HTTP clients already do.
  • With max_connections of 1, a connection closes after each response,
    because an idle connection gives up the only slot.
  • sync_dir is rejected at startup under strict authentication. Directory
    synchronization remains unavailable on Windows.

Verification

The release workflow
creates this Release only after validate, including the dependency freshness
check, Foundation and all eight native build/test jobs succeed at the tag's
SHA. The
container workflow
then builds both Linux architectures natively, verifies their SBOM and
provenance, publishes the multi-architecture tag and checks anonymous pulls.

v0.1.3

Choose a tag to compare

@github-actions github-actions released this 26 Oct 08:08

gcs-mimic 0.1.3

0.1.3 adds native Windows archives for x86-64 (x86_64-pc-windows-msvc) and
ARM64 (aarch64-pc-windows-msvc), so every supported target now ships: macOS,
Windows and Linux GNU/musl, each for ARM64 and x86-64. It also publishes
ghcr.io/shiroemons/gcs-mimic:0.1.3 for linux/amd64 and linux/arm64.
The 0.1.0 release notes
describe the included workflows, compatibility and known limitations.

Changes

  • gcs-mimic import fake-gcs-server now detects a source file replaced during
    import on Windows even when its size, contents and modification time match.
    Windows source fingerprints previously compared only size and modification
    time; they now also compare the volume, file index and change time.
  • On Windows, sync_dir is rejected with a diagnostic that directory
    synchronization is supported on Linux and macOS only. It previously claimed
    the directory was not writable.
  • Native test suites pass on Windows runners. The remaining fixes are
    test-only: process environments, file handle lifetimes during cleanup, path
    separators, file name and time range limits, and platform-specific
    connection errors.
  • Release preparation requires the manual dry run, including the publish job,
    to pass on the exact commit before tagging.

Compatibility and migration

No migration is required. The data-directory schema remains
PRAGMA user_version = 21, shared by 0.1.0 through 0.1.3. Windows archives
are unsigned, use the static MSVC runtime and keep the Windows recovery limits
in the 0.1.0 notes: normal restart and process termination are covered, OS
crash and power loss are not. Directory synchronization is not available on
Windows.

Verification

The release workflow
creates this Release only after validate, Foundation and all eight native
build/test jobs succeed at the tag's SHA, including Windows runtime import
checks. The
container workflow
then builds both Linux architectures natively, verifies their SBOM and
provenance, publishes the multi-architecture tag and checks anonymous pulls.

v0.1.2

Choose a tag to compare

@github-actions github-actions released this 26 Oct 04:30

gcs-mimic 0.1.2

0.1.2 adds native macOS archives for Apple Silicon (aarch64-apple-darwin) and
Intel (x86_64-apple-darwin) next to the four Linux archives, and publishes
ghcr.io/shiroemons/gcs-mimic:0.1.2 for linux/amd64 and linux/arm64.
Application behavior is unchanged from 0.1.1; the
0.1.0 release notes
describe the included workflows, compatibility and known limitations.

Changes

  • macOS archives return to the release matrix. Their native test suites now
    pass on GitHub runners: the TLS test fixtures no longer produce a CA with a
    duplicate basicConstraints extension under OpenSSL 1.1.1, and timing-based
    upload deadline tests keep enough margin on slower runners. Test-only changes.
  • Windows archives are still not published. Several Windows catalog,
    file-handle and synchronization tests fail on GitHub runners; use the
    container image on Windows hosts.
  • Manual dispatch of the release workflow now runs the publish job as a dry
    run up to the Release asset list.

Compatibility and migration

No migration is required. The data-directory schema remains
PRAGMA user_version = 21, shared by 0.1.0, 0.1.1 and 0.1.2. macOS archives are
unsigned and not notarized; macOS recovery limits in the 0.1.0 notes apply.

Verification

The release workflow
creates this Release only after validate, Foundation and all six native
macOS and Linux build/test jobs succeed at the tag's SHA. The
container workflow
then builds both Linux architectures natively, verifies their SBOM and
provenance, publishes the multi-architecture tag and checks anonymous pulls.

v0.1.1

Choose a tag to compare

@github-actions github-actions released this 26 Oct 02:34

gcs-mimic 0.1.1

0.1.1 is the first release with a container image:
ghcr.io/shiroemons/gcs-mimic:0.1.1 for linux/amd64 and linux/arm64.
It also ships the four Linux archives and SHA256SUMS. Application behavior is
unchanged from 0.1.0; its included workflows, compatibility notes, platform
verification and known limitations all apply. See the
0.1.0 release notes.

Changes

  • Container publication accepts the SLSA v1 provenance that BuildKit 0.34
    records. The v0.1.0 container step rejected valid images on this check, so
    0.1.0 has no container image; use 0.1.1.
  • A resumable-upload test gives catalog admission enough time on loaded CI
    runners. Test-only change.

Compatibility and migration

No migration from 0.1.0 is required. The data-directory schema remains
PRAGMA user_version = 21; 0.1.0 and 0.1.1 read and write the same data
directories. Follow the 0.1.0 notes for fake-gcs-server migration and backups.

Verification

The release workflow
creates this Release only after validate, Foundation and the four native Linux
build/test jobs succeed at the tag's SHA. The
container workflow
then builds both architectures natively, verifies their SBOM and provenance,
publishes the multi-architecture tag and checks anonymous pulls.